作业:
开发一个简单的python计算器
- 实现加减乘除及拓号优先级解析
- 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致
计算器源码:
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author: Mo import re def compute_multipy_divide(arg): value = arg[0] mch = re.search(\'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*\',value) if not mch: return content = re.search(\'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*\',value).group() if len(content.split(\'*\')) > 1: v1,v2 = content.split(\'*\') get_value = float(v1) * float(v2) else: v1,v2 = content.split(\'/\') get_value = float(v1) / float(v2) left,right = re.split(\'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*\',value,1) new_value = \'%s%s%s\' %(left,get_value,right) arg[0] = new_value compute_multipy_divide(arg) def compute_add_substract(arg): while True: if \'--\' in arg[0] or \'++\' in arg[0] or \'-+\' in arg[0] or \'+-\' in arg[0]: arg[0] = arg[0].replace(\'--\',\'+\') arg[0] = arg[0].replace(\'++\',\'+\') arg[0] = arg[0].replace(\'-+\',\'-\') arg[0] = arg[0].replace(\'+-\',\'-\') else: break if arg[0].startswith(\'-\'): arg[1] += 1 arg[0] = arg[0].replace(\'-\',\'&\') arg[0] = arg[0].replace(\'+\',\'-\') arg[0] = arg[0].replace(\'&\',\'+\') arg[0] = arg[0][1:] value = arg[0] mch = re.search(\'\d+\.*\d*[\+\-]{1}\d+\.*\d*\',value) if not mch: return content = re.search(\'\d+\.*\d*[\+\-]{1}\d+\.*\d*\',value).group() if len(content.split(\'+\')) >1: v1,v2 = content.split(\'+\') get_value = float(v1) + float(v2) else: v1,v2 = content.split(\'-\') get_value = float(v1) - float(v2) left,right = re.split(\'\d+\.*\d*[\+\-]{1}\d+\.*\d*\',str(value),1) new_value = \'%s%s%s\' %(left,get_value,right) arg[0] = new_value compute_add_substract(arg) def compute(expression): inp = [expression,0] compute_multipy_divide(inp) compute_add_substract(inp) count = divmod(inp[1],2) result = float(inp[0]) if count[1] == 1: result = result * (-1) return result def excute(expression): if not re.search(\'\(([\+\-\*\/]*\d+\.*\d*){2,}\)\',expression): result = compute(expression) return result content = re.search(\'\(([\+\-\*\/]*\d+\.*\d*){2,}\)\',expression).group() new_content = content[1:len(content)-1] new_list = re.split(\'\(([\+\-\*\/]*\d+\.*\d*){2,}\)\',expression,1) print(\'计算前:\',expression) left = new_list[0] right = new_list[2] final = compute(new_content) print(\'计算:%s=%s\' % (new_content, final)) new_expression = \'%s%s%s\' %(left,final,right) print(\'计算后:\', new_expression) print(\'上次计算结束\'.center(50,\'*\')) return excute(new_expression) def run(): while True: print(\' Oldboy Calc \'.center(50, \'*\')) str_input = input(\'(quit=q)>>:\').strip() if str_input == \'q\': exit() if len(str_input) == 0 : continue if len(str_input) >0 : no_space_str = re.sub(\'\s*\',\'\',str_input) final = excute(no_space_str) print(final) if __name__ == \'__main__\': run()
计算结果:
****************** Oldboy Calc ******************* (quit=q)>>:1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) 计算前: 1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) 计算:-40/5=-8.0 计算后: 1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) **********************上次计算结束********************** 计算前: 1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) 计算:9-2*5/3+7/3*99/4*2998+10*568/14=173545.88095238098 计算后: 1-2*((60-30+-8.0*173545.88095238098)-(-4*3)/(16-3*2)) **********************上次计算结束********************** 计算前: 1-2*((60-30+-8.0*173545.88095238098)-(-4*3)/(16-3*2)) 计算:60-30+-8.0*173545.88095238098=-1388337.0476190478 计算后: 1-2*(-1388337.0476190478-(-4*3)/(16-3*2)) **********************上次计算结束********************** 计算前: 1-2*(-1388337.0476190478-(-4*3)/(16-3*2)) 计算:-4*3=-12.0 计算后: 1-2*(-1388337.0476190478--12.0/(16-3*2)) **********************上次计算结束********************** 计算前: 1-2*(-1388337.0476190478--12.0/(16-3*2)) 计算:16-3*2=10.0 计算后: 1-2*(-1388337.0476190478--12.0/10.0) **********************上次计算结束********************** 计算前: 1-2*(-1388337.0476190478--12.0/10.0) 计算:-1388337.0476190478--12.0/10.0=-1388335.8476190479 计算后: 1-2*-1388335.8476190479 **********************上次计算结束********************** 2776672.6952380957 ****************** Oldboy Calc ******************* (quit=q)>>:q