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

作业 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

 

流程图:

详细代码:

  1 #!usr/bin/env python
  2 #-*-coding:utf-8-*-
  3 # Author calmyan
  4 import re
  5 #b='1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
  6 #b='1 - 2 * ( (60-30 +(-40/5) * (9-2**5//3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)// (16-3*2) )'
  7 #print(b)
  8 
  9 def list_format(b):#格式化字符串函数
 10     b=re.sub(' ','',b)
 11     b=[i for i in re.split('(\-?\d+\.*\d*)',b) if i]#循环判断,i 不为空,添加到列表 去空字符 -开头加后面的数字
 12     #print(b)
 13     tmp_list=[]#定义一个临时列表
 14     while True:
 15         if len(b)==0:break#如果列表为空就退出
 16         emp=b.pop(0)#取出第一个元素
 17         if (len(tmp_list)==0 and  re.search('^\-\d*$',emp)) or (len(tmp_list)>0 and  re.search('[\+\-\*\/\(\)]$',tmp_list[-1]) ):#判断开头与中间的负数
 18             tmp_list.append(emp)
 19             continue
 20         sny_nl=[i for i in re.split('([\+\-\*\/\(\)])',emp) if i]#对运算符进行分割
 21 
 22         for index, i in enumerate(sny_nl):
 23             if  i==' ':#去空格判断
 24                 sny_nl.pop(index)#删除空格项
 25         tmp_list+=sny_nl
 26 
 27     return tmp_list#返回列表
 28 
 29 def Prioty(str_n,i):#比较优先级函数
 30     lev1=['+','-']
 31     lev2=['*','/']
 32     lev3=['(']
 33     lev4=[')']
 34     if str_n in lev1:
 35         if i in lev2 or i in lev3:#如果str_n 为+ - i 在2,3级时返回小于
 36             return 1
 37         else:
 38             return 3
 39     elif str_n in lev2:#如果str_n 为*/ i 在3级时返回小于
 40         if i in lev3:
 41             return 1
 42         else:
 43             return 3
 44     elif str_n in lev3:#如果str_n 为(i 在4级时返回等于
 45         if i in lev4:
 46             return 2
 47         else:
 48             return 1
 49 
 50 def sny(str):#判断是否为运算符
 51     sny_l=['+','-','*','/','**','//','(',')']
 52     tag=False
 53     if str in sny_l:
 54         return True#是运算符返回真
 55     else:
 56         return tag
 57 
 58 def opera(num1,operation,num2):#运算函数
 59     res=0
 60     if operation=='+':
 61         res=num1+num2
 62     if operation=='-':
 63         res=num1-num2
 64     if operation=='*':
 65         res=num1*num2
 66     if operation=='/':
 67         res=num1/num2
 68     return res
 69 
 70 def main(c):#主函数
 71     numbe_list=[]#定义数字堆栈
 72     sny_list=[]#定义运算符堆栈
 73     for i in c:
 74         if sny(i):#不是运算运
 75             while True:
 76                 #print(numbe_list)
 77                 #print(sny_list)
 78                 if len(sny_list)==0:#如果列表为空,即第一个就无条件加入
 79                     sny_list.append(i)
 80                     break
 81                 prty=Prioty(sny_list[-1],i)#
 82                 if prty==1:#如果为一级
 83                     sny_list.append(i)#运算符继续添加
 84                     break
 85                 elif prty==2:#如果为二级
 86                     sny_list.pop()#运算符要取出最后一个
 87                     break
 88                 elif prty==3:#如果为三级
 89                     operation=sny_list.pop()#运算符==取出最后一个
 90                     num2=numbe_list.pop()#取出数字二
 91                     num1=numbe_list.pop()#取出数字一
 92                     numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果
 93                     #print(numbe_list,sny_list)
 94                     continue
 95         else:
 96             i = float(i)#转为浮点数
 97             numbe_list.append(i)#添加到数字列表
 98     else:
 99         operation=sny_list.pop()#运算符==取出最后一个
100         num2=numbe_list.pop()#取出数字二
101         num1=numbe_list.pop()#取出数字一
102         numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果
103         #print(numbe_list,sny_list)
104         if len(sny_list):#如果运算符列表不为空再做一个运算
105             operation=sny_list.pop()#运算符==取出最后一个
106             num2=numbe_list.pop()#取出数字二
107             num1=numbe_list.pop()#取出数字一
108             numbe_list.append(opera(num1,operation,num2))#数字列表添加运算的结果
109     return numbe_list[0]
110 
111 #程序开始
112 print("\033[35;1m欢迎使用python简易计算器\033[0m".center(60,'='))
113 if __name__ =='__main__':
114     while True:
115         b=input('请输入你要计算的内容,按\033[31;1mQ/q\033[0m退出:')
116         if b=='q' or b=='Q':
117             exit()
118         #print(c)
119         try:
120             c=list_format(b)#运行输入函数格式化字符串,存入列表
121             number=main(c)
122             print(number)
123         except  Exception as e:#出错可返回操作
124             print('输入有误,请重新输入')
View Code

 

posted @ 2017-05-24 18:49  莫柔落切  阅读(738)  评论(0编辑  收藏  举报