# !/usr/bin/env python3 # _*_coding:utf-8_*_ ''' 实现模拟计算器的功能: 公式:1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) 思路: 括号的计算优先级最高,应该优先计算括号内的式子,然后将值代替会原式子,循环,接着做惩处运算,最后是加减运算,然后弹出结果, # print(eval('1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))')) ''' import re symbol = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '+', '*', '/', '(', ')'] def check(formula): ''' 检查输入的公式的正确性: 除了十个数字和六个符号,其他的一律判错,但是这样会限制运算规则,目前先是这样规划 :param formula: :return: ''' symbol_flag = True formula = re.sub(r'\s*', '', formula) cal_list = list(formula) for item in cal_list: if item not in symbol: symbol_flag = False if not symbol_flag: return 1 else: return formula def change(formula): ''' 替换出现两个运算符在一起的情况: :param formula: :return: ''' formula = formula.replace('--', '+') formula = formula.replace('++', '+') formula = formula.replace('**', '*') formula = formula.replace('//', '=') formula = formula.replace('*+', '*') formula = formula.replace('/+', '/') return formula def chengchu(arg): val = arg[0] match = re.search(r'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val) if not match: return content = re.search(r'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val).group() if len(content.split('*')) > 1: n1, n2 = content.split('*') value = float(n1) * float(n2) else: n1, n2 = content.split('/') value = float(n1) / float(n2) before, after = re.split(r'\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val, 1) new_str = '%s%s%s' % (before, value, after) arg[0] = new_str print(arg) chengchu(arg) def jiajian(arg): while True: if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__( "--"): 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:] val = arg[0] match = re.search(r'\d+\.?\d*[-+]{1}\d+\.?\d*', val) if not match: return content = re.search(r'\d+\.?\d*[-+]{1}\d+\.?\d*', val).group() if len(content.split('+')) > 1: n1, n2 = content.split('+') value = float(n1) + float(n2) else: n1, n2 = content.split('-') value = float(n1) - float(n2) before, after = re.split(r'\d+\.?\d*[-+]{1}\d+\.?\d*', val, 1) new_str = '%s%s%s' % (before, value, after) arg[0] = new_str jiajian(arg) def compute(formula): ''' 操作加减乘除:根据操作 :param formula: :return: ''' inp = [formula, 0] # chengchu(inp) jiajian(inp) if divmod(inp[1], 2)[1] == 1: result = float(inp[0]) result = float(result) * -1 else: result = float(inp[0]) return result def calcultor(formula): ''' 递归处理括号,并计算括号内的式子,将结果返回做替换, :param formula: :return: ''' # 没有括号了 if not re.search(r'\(([-+*/]*\d+\.*\d*){2,}\)', formula): final = compute(formula) return final # 取出其中的一个括号,然后计算 content = re.search(r'\(([-+*/]*\d\.*\d*){2,}\)', formula).group() # 分裂表达式 before, nothing, after = re.split(r'\(([-+*/]*\d+\.*\d*){2,}\)', formula, 1) # 计算括号里的内容 content = content[1:len(content) - 1] ret = compute(content) # 计算完后然后拿到结果,然后重新拼接成一个新的式子 formula = '%s%s%s' % (before, ret, after) return calcultor(formula) # s='1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))' # calcultor(s) def main(): print('欢迎使用计算器'.center(60, '#')) while True: formula = input('计算式>>:').strip() if formula == 'q': exit() elif len(formula) == 0: continue else: formula=check(formula) if formula == 1: continue else: result = calcultor(formula) print('计算结果为:\033[1;31;1m %s\033[0m' % (result)) try: print('正确答案是:\033[1;31;1m %s\033[0m' %(eval(formula))) except: print('无法计算') if __name__ == '__main__': main()