#-*- coding:utf-8 -*-#Author:'Yang'
importre'''去除重复的加减运算符'''
defremove_duplicates(formula):
formula= formula.replace("++","+")
formula= formula.replace("+-","-")
formula= formula.replace("-+","-")
formula= formula.replace("--","+")returnformula'''乘除运算函数: multiply-divide'''
defmul_div(formula):
value_list=re.split('[*/]',formula)
operator_list=re.findall('[*/]',formula)
res_mul=float(value_list[0])for i inrange(len(operator_list)):if operator_list[i]=="*":
res_mul*=float(value_list[i+1])elif operator_list[i]=="/":
res_mul/=float(value_list[i+1])#print("\033[31;1m[%s]运算结果=\033[0m" %formula, res_mul)
returnres_mul'''计算不含括号的加减乘除'''
defcalc(formula):
value_list=[]
operator_list=[]if re.match("^\-",formula): #第一个数是负数,"-2.0*3/3.2*1+1+2*3*1-4/2"
minus_formula=re.match(r"^\-\d+(?:\.\d+)?([*/]\d+(?:\.\d+)?)*",formula).group() #匹配第一个数是负数的式子 "-2.0*3/3.2*1"
value_list.append(mul_div(minus_formula)) #乘除运算 -2.0*3/3.2*1=-1.875
other_formula=formula[len(minus_formula):len(formula)] #获取剩下未计算的式子"+1+2*3*1-4/2"
operator_list=re.findall('\+|\-',other_formula) #获取式子"+1+2*3*1-4/2"中的+-运算符列表['+', '+', '-']
temp_value_list=re.split('\+|\-',other_formula) #获取式子"+1+2*3*1-4/2"中的数字列表[-1.875, '1', 6.0, 2.0]
else: #第一个数是正数,"1+2*3*1-4/2-2"
operator_list=re.findall('\+|\-',formula) #['+','-','-']
temp_value_list=re.split('\+|\-',formula) #['1','2*3*1','4/2','2']
value_list=[] #['1','6','2','2']
iftemp_value_list:for i intemp_value_list:if re.search('\*|\/',i): #匹配乘除,进行各个列表元素的乘除运算,并赋值到新的列表
value_list.append(mul_div(i))elif re.search(r'\-?\d+(?:\.\d+)?',i): #匹配(正负)小数和整数,赋值到新的列表
value_list.append(i)#print(value_list)
#print(operator_list)
res_sum=float(value_list[0])for i in range(len(operator_list)): #进行加减运算
if operator_list[i]=="+":
res_sum+=float(value_list[i+1])elif operator_list[i]=="-":
res_sum-=float(value_list[i+1])#print("\033[31;1m[%s]运算结果=\033[0m" %formula, res_sum)
returnres_sum'''递归检测括号并计算'''
defparanteses(formula):
formula=formula.replace(" ","") #清除空格字符
p=r"\([^()]*\)" #匹配最里层括号
if re.search(p,formula): #有括号,需要递归处理
ret=re.search(p,formula).group() #获取含括号的匹配值
if ret[1]=="-": #判断括号内第一个出现的字符是不是“-”
formula=formula.replace(ret,str(calc(ret[1:-1]))) #计算括号内的值,并将值替换至匹配处
p_munis=r'\d+(?:\.\d+)?[*/]\-\d+(?:\.\d+)?' #匹配乘除负数(负整数、负小数)
if re.search(p_munis,formula): #判断是乘除负数,则需要特殊处理,否则跳过
ret_munis=re.search(p_munis,formula).group() #获取含乘除负数的运算式,如2*-5
#print(re.search("[*/]\-",ret_munis).group()) #匹配*-或/-
#print(re.search("[*/]\-",ret_munis).group()[0]) #匹配*-或/-,并取第一个运算符*或/
#将运算式中 *-或/-的 -提取到运算式前面,如2*-5变成-2*5
formula=formula.replace(ret_munis,"-"+ret_munis.replace(re.search("[*/]\-",ret_munis).group(),re.search("[*/]\-",ret_munis).group()[0]))
formula=remove_duplicates(formula)else:
formula=formula.replace(ret,str(calc(ret[1:-1])))returnparanteses(formula)else:#无括号,直接计算
print("\033[32;1m运算结果=\033[0m",calc(formula))returnformulaif __name__=='__main__':print("\033[36;1m欢迎使用 Python计算器V1.0 By Yang\033[0m".center(70,"#"))whileTrue:
cal_input=input("\033[32;1m请输入计算公式,输入q退出程序>>\033[0m")if cal_input=='q':print("\033[31;1m退出Python计算器V1.0,谢谢您的使用!\033[0m")break
#elif re.search("\s",cal_input):
#print("\033[31;1m不能包含空白字符!\033[0m")
else:
paranteses(cal_input)#######################以下为调试用代码#####################
#'''调用mul_div计算不包含括号的乘除运算'''
#cal_input0="-2.0*3.2"
#mul_div(cal_input0)
## calc(cal_input0)
#print("分割线,以上调试通过".center(50,"*"))
# #'''调用calc计算不包含括号的加减乘除运算'''
#cal_input1="-2.0*3/3.2*1+1+2*3*1-4/2"#第一个数为负数
#calc(cal_input1)
#print("分割线,以上调试通过".center(50,"*"))
#cal_input2="1+2*3*1-4/2-2" #第一个数为正数
#calc(cal_input2)
#print("分割线,以上调试通过".center(50,"*"))
#cal_input5=" -1388337.0476190478 +12.0/ 10.0 "
#calc(cal_input5)
#cal_input3="1-(5-(1+1)*2+3)/(-1)-(2+1)*2+7" #10.0 ,"1+((1+1)+3)-(1+3)"
#paranteses(cal_input3)
#cal_input4="5+(1+((1+1+1)*1+2)*2+5)/2-7" #6
#paranteses(cal_input4)
#cal_input6="1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )"
#paranteses(cal_input6)