协程和装饰器完成简易计算器

 1 import functools as ft
 2 import itertools as it
 3 
 4 OPERATORS='+','-','/','*'
 5 EXIT_COMMANDS='exit','quit'
 6 
 7 #验证最近输入的三个数是否能构成计算公式
 8 def can_calculate(state):
 9     if len(state)<3:
10         return False
11     *_,i1,op,i2=state       #unpack state并从倒数开始赋值,list的倒数第一个赋值给i2,倒数第二个赋值给op,倒数第三个赋值给i1,剩下的赋值给*_
12     return isinstance(i1,float) and op in OPERATORS and isinstance(i2,float)
13 
14 #计算
15 def calculate(state):
16     *_,i1,op,i2=state
17     if op=='+':
18         result=i1+i2
19     elif op=='-':
20         result=i1-i2
21     elif op=='/':
22         result=i1/i2
23     elif op=='*':
24         result=i1*i2
25     else:
26         raise ValueError('Invalid operator!')
27     print('%f %s %f=%f'%(i1,op,i2,result))
28     return result
29 
30 #验证输入是否合法
31 def validate_input(fnc):
32     def inner():
33         i=fnc()     #i=get_input()=input()
34         try:
35             i=float(i)
36         except ValueError:
37             pass
38         if isinstance(i,float) or i in OPERATORS or i in EXIT_COMMANDS:
39             return i
40         return None
41 
42     return inner
43 
44 #通过装饰器验证合法输入并返回
45 @validate_input
46 def get_input():    #get_input=validate_input(get_input)    i=get_input()=inner()
47     return input()
48 
49 def process_input():
50     state=[]
51     while True:
52         update=yield
53         state.append(update)      #state=[1,*,3,+,4]
54         if can_calculate(state):
55             result=calculate(state)
56             state.append(result)    #state=[1,*,3,3,7]
57 
58 
59 #获取输入计算器的值并将值发送给process_input()函数
60 def calculator():
61     g=process_input()
62     g.send(None)
63     while True:         #i=get_input()=inner()
64         i=get_input()   #如果输入的值为非数字或则操作符验证器将返回None
65         if i is None:
66             print('Please enter a number or an operator')
67             continue
68         if i in EXIT_COMMANDS:
69             break
70         g.send(i)
71 
72 calculator()

运行结果如下

 1 3
 2 *
 3 5
 4 3.000000 * 5.000000=15.000000
 5 -
 6 1
 7 15.000000 - 1.000000=14.000000
 8 /
 9 3
10 14.000000 / 3.000000=4.666667
11 *
12 5
13 4.666667 * 5.000000=23.333333
14 *
15 6
16 23.333333 * 6.000000=140.000000
17 /
18 22
19 140.000000 / 22.000000=6.363636
20 exit

 

posted @ 2018-05-02 15:04  xajh00789  阅读(186)  评论(0编辑  收藏  举报