# !/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()