1 importre2 importfunctools3
4
5 defminus_operator_handler(formula):6 '''处理一些特殊的减号运算'''
7 minus_operators = re.split("-",formula)8 calc_list= re.findall("[0-9]",formula)9 if minus_operators[0] == '': #第一值肯定是负号
10 calc_list[0] = '-%s' %calc_list[0]11 res = functools.reduce(lambda x,y:float(x) -float(y), calc_list)12 print("\033[33;1m减号[%s]处理结果:\033[0m" %formula, res )13 returnres14
15 defremove_duplicates(formula):16 formula = formula.replace("++","+")17 formula = formula.replace("+-","-")18 formula = formula.replace("-+","-")19 formula = formula.replace("--","+")20 formula = formula.replace("- -","+")21 returnformula22 defcompute_mutiply_and_dividend(formula):23 '''算乘除,传进来的是字符串噢'''
24 operators = re.findall("[*/]", formula )25 calc_list = re.split("[*/]", formula )26 res =None27 for index,i inenumerate(calc_list):28 ifres:29 if operators[index-1] == "*":30 res *=float(i)31 elif operators[index-1] == "/":32 res /=float(i)33 else:34 res =float(i)35
36 print("\033[31;1m[%s]运算结果=\033[0m" %formula, res )37 returnres38 defhandle_minus_in_list(operator_list,calc_list):39 '''有的时候把算术符和值分开后,会出现这种情况 ['-', '-', '-'] [' ', '14969037.996825399 ', ' ', '12.0/ 10.0 ']40 这需要把第2个列表中的空格都变成负号并与其后面的值拼起来,恶心死了41 '''
42 for index,i inenumerate(calc_list):43 if i == '': #它其实是代表负号,改成负号
44 calc_list[index+1] = i + calc_list[index+1].strip()45 defhandle_special_occactions(plus_and_minus_operators,multiply_and_dividend):46 '''有时会出现这种情况 , ['-', '-'] ['1 ', ' 2 * ', '14969036.7968254'],2*...后面这段实际是 2*-14969036.7968254,需要特别处理下,太恶心了'''
47 for index,i inenumerate(multiply_and_dividend):48 i =i.strip()49 if i.endswith("*") or i.endswith("/"):50 multiply_and_dividend[index] = multiply_and_dividend[index] + plus_and_minus_operators[index] + multiply_and_dividend[index+1]51 del multiply_and_dividend[index+1]52 delplus_and_minus_operators[index]53 returnplus_and_minus_operators,multiply_and_dividend54 defcompute(formula):55 '''这里计算是的不带括号的公式'''
56
57 formula = formula.strip("()") #去除外面包的拓号
58 formula = remove_duplicates(formula) #去除外重复的+-号
59 plus_and_minus_operators = re.findall("[+-]", formula)60 multiply_and_dividend = re.split("[+-]", formula) #取出乘除公式
61 if len(multiply_and_dividend[0].strip()) == 0:#代表这肯定是个减号
62 multiply_and_dividend[1] = plus_and_minus_operators[0] + multiply_and_dividend[1]63 delmultiply_and_dividend[0]64 delplus_and_minus_operators[0]65
66 plus_and_minus_operators,multiply_and_dividend=handle_special_occactions(plus_and_minus_operators,multiply_and_dividend)67 for index,i inenumerate(multiply_and_dividend):68 if re.search("[*/]",i):69 sub_res =compute_mutiply_and_dividend(i)70 multiply_and_dividend[index] =sub_res71
72 #开始运算+,-
73 print(multiply_and_dividend, plus_and_minus_operators)74 total_res =None75 for index,item inenumerate(multiply_and_dividend):76 if total_res: #代表不是第一次循环
77 if plus_and_minus_operators[index-1] == '+':78 total_res +=float(item)79 elif plus_and_minus_operators[index-1] == '-':80 total_res -=float(item)81 else:82 total_res =float(item)83 print("\033[32;1m[%s]运算结果:\033[0m" %formula,total_res)84 returntotal_res85
86 defcalc(formula):87 '''计算程序主入口, 主要逻辑是先计算拓号里的值,算出来后再算乘除,再算加减'''
88 parenthesise_flag =True89 calc_res = None #初始化运算结果为None,还没开始运算呢,当然为None啦
90 whileparenthesise_flag:91 m = re.search("\([^()]*\)", formula) #找到最里层的拓号
92 ifm:93 #print("先算拓号里的值:",m.group())
94 sub_res =compute(m.group())95 formula =formula.replace(m.group(),str(sub_res))96 else:97 print('\033[41;1m----没拓号了...---\033[0m')98
99 print('\n\n\033[42;1m最终结果:\033[0m',compute(formula))100 parenthesise_flag = False #代表公式里的拓号已经都被剥除啦
101
102 if __name__ == '__main__':103
104 #res = calc("1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )")
105 res = calc("1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )")