实战2-计算器:输入这段公式("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),运行程序需计算出结果
#!usr\bin\env\python
# -*- coding:utf-8 -*9
import re
import functools
def minus_operator_handler(formual):
#特殊减法运算,采取正则表达式的方式匹配字符
minus_operator=re.split("-",formual)
calc_list=re.fingall("[0-9]",formual)
if minus_operatos[0]=='':
calc_list[0]="-%s",% calc_list[0]
res=functools.reduce(lambda x,y:float(x)-float(y),formual,res)
print("\033[1m;运算结果为\033[0m",formual,res)
return res
def remove_duplicates(formual):
#双重符号运算
formual=formual.replace("++","+")
formual=formual.replace("+-","-")
formual=formual.replace("-+","+")
formual=formual.replace("--","+")
formual=formual.replace("- -","+")
return formual
def mutiply_and_dividend(formual):
#算乘除
operators=re.findall("[*/]",formual)
calc_list=re.split("[*/]",formual)
res =None #刚进入计算界面,还没计算时值为None
for index,i in enumerate(calc_list):
if res:
if operators[index-1]=="*":
res *=float(i)
eliif operators[index-1]=="/":
res /=float(i)
else:
res=float(i)
print("\033[1m;最终运算结果为\033[0m",res,formual)
return res
def handle_minus_in_list(operator_list,calc_list): #特殊情况处理
#有的时候把算术符和值分开后,会出现这种情况 ['-', '-', '-'] [' ', '14969037.996825399 ', ' ', '12.0/ 10.0 ']需要把第2个列表中的空格变成负号与后面的值拼接起来
for index,i in enumerate(calc_list):
if i=='': #这个位置实则是负号,将之改成负数
calc_list[index+1]=i+calc_list[index+1].strip() #将列表中的进行字符转义
def handle_special_occactions(plus_and_minus_operators,mutiply_and_dividend):
#有时会出现这种情况 , ['-', '-'] ['1 ', ' 2 * ', '14969036.7968254'],2*...后面这段实际是 2*-14969036.7968254,需要特别处理
for index,i in enumearter(mutiply_and_dividend):
i=i.strip() #将i的值字符串化
if i.endswith("*") or i.endswith("/"):
mutiply_and_dividend[index]=mutiply_and_dividend[index]+plus_and_minus_operators[index]+mutiply_and_dividend[index+1]
del mutiply_and_dividend[index+1] #使用Index扩展完临时列表后再用del进行删除
del plus_and_minus_operators[index]
return plus_and_minus_operators,mutiply_and_dividend
def compute(formual):
#计算不带括号的值和加减法,首先利用公式去除带括号的值
formual=formual.strip("()") #去除外层的括号
formual=remove_duplicates(formual) #调用函数去除双重符号
plus_and_minus_operators=re.findall("[+-]",formual)
mutiply_and_dividend =re.split("[+-]",formual)
if len(mutiply_and_dividend[0].strip())==0: #这里一定是负号
mutiply_and_dividend[1]=plus_and_minus_operators[0]+ mutiply_and_dividend[1]
del plus_and_minus_operators[0] #将扩展的长度删除
del mutiply_and_dividend[0]
#调用特殊处理函数的方法,对加减乘除进行处理
plus_and_miuns_operators,mutiply_and_dividend=handle_special_occactions(plus_and_minus_operators,mutiply_and_dividend)
for index,i in enumearter(mutiply_and_dividend): #利用For遍历乘除函数,使用正则表达式匹配公式中的乘除符号,最后调用乘除函数计算数值
if re.search("[*/]",i):
sub_res=mutiply_and_divideng(i)
mutiply_and_dividend[index]=sub_res
#开始计算,加减法
print( plus_and_minus_operators,mutiply_and_dividend)
total_res=None:
for index,item in enumearter(mutiply_and_dividend):
if plus_and_minus_operators[index -1]=='+':
total_res +=float(item)
elif plus_and_minus_operators[index -1]=='-':
total_res -=float(item)
else:
total_res=float(item)
print("\033[1m;最终运算结果为\033[0m" %total_res,formual)
return total_res
def calc_main(formual):
#计算器程序的主入口,主要逻辑是先计算括号里面的值,算出来后算乘除,再算加减法
#设立一个标志位
pare_flag=Flase
calc_res=None
while pare_flag:
m=re.search("\([^()]*\)",formual)
if m :
#先计算括号里的值,利用m.group()方法显示计算出的值
sub_res=compute(m.group())
formual=formual.replace(m.group(),str(sub_res))
else:
print("\033[1m;括号已经运算完毕\033[0m")
print("\033[1m;最终运算结果为\033[0m",compute(formual))
pare_flag=True
if __name__='__main__':
res=calc_main("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)