python第二十一天---昨天没写完作业

时间:2022-03-22 07:00:24

作业 2, 模拟计算器开发:
实现加减乘除及拓号优先级解析
用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致  2776672.6952380957

流程图:

python第二十一天---昨天没写完作业

详细代码:

 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
import re
#b='1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
#b='1 - 2 * ( (60-30 +(-40/5) * (9-2**5//3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)// (16-3*2) )'
#print(b) def list_format(b):#格式化字符串函数
b=re.sub(' ','',b)
b=[i for i in re.split('(\-?\d+\.*\d*)',b) if i]#循环判断,i 不为空,添加到列表 去空字符 -开头加后面的数字
#print(b)
tmp_list=[]#定义一个临时列表
while True:
if len(b)==0:break#如果列表为空就退出
emp=b.pop(0)#取出第一个元素
if (len(tmp_list)==0 and re.search('^\-\d*$',emp)) or (len(tmp_list)>0 and re.search('[\+\-\*\/\(\)]$',tmp_list[-1]) ):#判断开头与中间的负数
tmp_list.append(emp)
continue
sny_nl=[i for i in re.split('([\+\-\*\/\(\)])',emp) if i]#对运算符进行分割 for index, i in enumerate(sny_nl):
if i==' ':#去空格判断
sny_nl.pop(index)#删除空格项
tmp_list+=sny_nl return tmp_list#返回列表 def Prioty(str_n,i):#比较优先级函数
lev1=['+','-']
lev2=['*','/']
lev3=['(']
lev4=[')']
if str_n in lev1:
if i in lev2 or i in lev3:#如果str_n 为+ - i 在2,3级时返回小于
return 1
else:
return 3
elif str_n in lev2:#如果str_n 为*/ i 在3级时返回小于
if i in lev3:
return 1
else:
return 3
elif str_n in lev3:#如果str_n 为(i 在4级时返回等于
if i in lev4:
return 2
else:
return 1 def sny(str):#判断是否为运算符
sny_l=['+','-','*','/','**','//','(',')']
tag=False
if str in sny_l:
return True#是运算符返回真
else:
return tag def opera(num1,operation,num2):#运算函数
res=0
if operation=='+':
res=num1+num2
if operation=='-':
res=num1-num2
if operation=='*':
res=num1*num2
if operation=='/':
res=num1/num2
return res def main(c):#主函数
numbe_list=[]#定义数字堆栈
sny_list=[]#定义运算符堆栈
for i in c:
if sny(i):#不是运算运
while True:
#print(numbe_list)
#print(sny_list)
if len(sny_list)==0:#如果列表为空,即第一个就无条件加入
sny_list.append(i)
break
prty=Prioty(sny_list[-1],i)#
if prty==1:#如果为一级
sny_list.append(i)#运算符继续添加
break
elif prty==2:#如果为二级
sny_list.pop()#运算符要取出最后一个
break
elif prty==3:#如果为三级
operation=sny_list.pop()#运算符==取出最后一个
num2=numbe_list.pop()#取出数字二
num1=numbe_list.pop()#取出数字一
numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果
#print(numbe_list,sny_list)
continue
else:
i = float(i)#转为浮点数
numbe_list.append(i)#添加到数字列表
else:
operation=sny_list.pop()#运算符==取出最后一个
num2=numbe_list.pop()#取出数字二
num1=numbe_list.pop()#取出数字一
numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果
#print(numbe_list,sny_list)
if len(sny_list):#如果运算符列表不为空再做一个运算
operation=sny_list.pop()#运算符==取出最后一个
num2=numbe_list.pop()#取出数字二
num1=numbe_list.pop()#取出数字一
numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果
return numbe_list[0] #程序开始
print("\033[35;1m欢迎使用python简易计算器\033[0m".center(60,'='))
if __name__ =='__main__':
while True:
b=input('请输入你要计算的内容,按\033[31;1mQ/q\033[0m退出:')
if b=='q' or b=='Q':
exit()
#print(c)
try:
c=list_format(b)#运行输入函数格式化字符串,存入列表
number=main(c)
print(number)
except Exception as e:#出错可返回操作
print('输入有误,请重新输入')