如何减少代码的循环复杂度?

时间:2019-08-15 14:01:26

标签: python cyclomatic-complexity

所以我正在尝试用python创建一个聊天机器人。在线ide(repl.it)是我用来从任何地方运行代码的工具。圈复杂度极限为15。我想在不超出极限的情况下使某些东西真正复杂,这可能吗?

import random

greeting = ["Hello!","Hi!","Hey!","Hello my name is IFuture!","How may I help you?"]
farewell = ["Bye","Bye bye","See you soon","Don't forget about me!","See you next time","See you"]
catchthat = ["I didn't catch that.","Sorry, I couldn't understand what you said.","Could you say that again?","Could you type in english?"]
notnice = ["That wasn't nice.","Next time try to say that nicer.","Try being nice.","You have more friends when you are nice."]
def run():
  global greeting,farewell,catchthat
  userinputa = str(input(">>>")).lower()
  userinput = userinputa.split()
  if "hello" in userinput or "hey" in userinput or "hi" in userinput: 
    print(random.choice(greeting))
  elif  "swear1" in userinput or "swear2" in userinput or "swear3" in userinput or "swear4" in userinput or "swear6" in userinput:
    if "you" in userinput:
      print(random.choice(swear back)
    else:
      #print(random.choice(notnice))
      print("swear back")
  elif "what" in userinput:
    if "can" in userinput:
      if "you" in userinput:
        if "do" in userinput:
          print("Try ?help or anything I am made to do.")
    elif "is" in userinput:
      try:
        num1 = int(userinput[2])
        num2 = int(userinput[4])
        conversion = str(userinput[3])
        if conversion in ["add","plus","addition","sum","+"]:
          print(num1+num2)
        elif conversion in ["times","multiply","*","x"]:
          print(num1*num2)
        elif conversion in ["divide","/"]:
          print(num1/num2)
      except:
        print("Try using spaces for example 5*5 would be 5 * 5.")
  else:
    print(random.choice(catchthat))




while True:
  run()

对不起,我的代码效率低下。

1 个答案:

答案 0 :(得分:1)

要减少循环复杂性,您必须减少if语句的数量,通过为每个代码块创建新函数来减少函数中的代码行数

我刚刚将您的“运行”功能代码的循环复杂度从19降低到了3(根据this网站):

from itertools import chain    
import random

GREETING = ["Hello!","Hi!","Hey!","Hello my name is IFuture!","How may I help you?"]
FAREWELL = ["Bye","Bye bye","See you soon","Don't forget about me!","See you next time","See you"]
CATCHTHAT = ["I didn't catch that.","Sorry, I couldn't understand what you said.","Could you say that again?","Could you type in english?"]
NOTNICE = ["That wasn't nice.","Next time try to say that nicer.","Try being nice.","You have more friends when you are nice."]

USER_GREETING = frozenset({"hello", "hey", "hi"})
USER_SWEAR = frozenset({"swear1",  "swear2", "swear3",  "swear4", "swear6"})

def print_sum(x, y): 
    print(x + y)

def print_mul(x, y):
    print(x * y)

def print_div(x, y):
    print(x / y)

CONVERSATION_OPERATION = {"add" : print_sum,
    "plus" : print_sum,
    "addition" : print_sum,
    "sum" : print_sum,
    "+" : print_sum,
    "times" : print_mul,
    "multiply" : print_mul,
    "*" : print_mul,
    "x" : print_mul,
    "divide" : print_div,
    "/" : print_div
}

def swer_response(userinput):
    if "you" in userinput:
        return 'swear back1'

    #print(random.choice(notnice))
    return "swear back2"

def what_is(userinput):
    try:
        num1 = int(userinput[2])
        num2 = int(userinput[4])
        conversion = str(userinput[3])
        print_operation = CONVERSATION_OPERATION[conversion]
        print_operation(num1, num2)
    except:
        print("Try using spaces for example 5*5 would be 5 * 5.")

WHAT_CAN_YOU_DO = frozenset({"what", "can", "you","do" })
WHAT_IS = frozenset({"what", "is"})

REPLY_SEQ_AT_LEAST_ONE = [USER_GREETING, USER_SWEAR]
REPLY_SEQ_SUBSET = [WHAT_CAN_YOU_DO, WHAT_IS]

REPLY = {
    USER_GREETING: lambda _:  print(random.choice(GREETING)),
    USER_SWEAR: lambda x:  print(swer_response(x)),
    WHAT_CAN_YOU_DO: lambda _: print("Try? help or anything I am made to do."),
    WHAT_IS: lambda x: what_is(x)
}

def at_least_one_word(userinput):
    yield from (r for r in REPLY_SEQ_AT_LEAST_ONE if r.intersection(userinput))

def subset(userinput):
    yield from (r for r in REPLY_SEQ_SUBSET if r.issubset(userinput))


def run():
    userinputa = str(input(">>>")).lower()
    userinput = set(userinputa.split()) 

    for reply in chain(at_least_one_word(userinput), subset(userinput)) :
        if reply.intersection(userinput):
            reply_func = REPLY[reply]
            reply_func(userinput)
            return

    print(random.choice(CATCHTHAT))


run()