计算器
功能需求:
-
用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致。
-
实现加减乘除
-
满足优先级
所需知识点:
-
流程控制
-
函数
-
函数递归
-
正则表达式
-
常用数据类型列表的操作
代码逻辑:
详细代码:
为了方便明白整个逻辑过程,代码中的好多调试信息没有去掉。
1 #_*_coding:utf-8_*_ 2 __author__ = 'jieli' 3 import re 4 import sys 5 6 7 def remove_space(data_list): 8 '''去除列表中的空格元素''' 9 for i in data_list: 10 if type(i) is not int: 11 if len(i.strip()) == 0: 12 data_list.remove(i) 13 return data_list 14 15 def fetch_data_from_bracket(data_list,first_right_bracket_pos): 16 '''用递归的形式取出每一对括号里的数据并进行运算且得出结果''' 17 print 'data list:',data_list 18 19 left_bracket_pos,right_bracket_pos = data_list.index('('),data_list.index(')') +1 20 print '\033[31;1mleft bracket pos:%s right_bracket_pos: %s\033[0m' %(left_bracket_pos,first_right_bracket_pos) 21 data_after_strip = data_list[left_bracket_pos:right_bracket_pos] 22 23 if data_after_strip.count("(") > 1: 24 print 'fetch_data_from_bracket:%s \033[31;1m%s\033[0m left pos:%s' %(data_after_strip,data_after_strip[1:] , left_bracket_pos) 25 #return fetch_data_from_bracket(data_after_strip[left_bracket_pos+1:],first_right_bracket_pos) 26 return fetch_data_from_bracket(data_after_strip[1:],first_right_bracket_pos) 27 28 else: 29 print 'last:',len(data_after_strip),data_after_strip 30 bracket_start_pos = first_right_bracket_pos - len(data_after_strip) +1 # (takes two position 31 calc_res = parse_operator(data_after_strip) 32 return calc_res, bracket_start_pos,first_right_bracket_pos +1 #') takes one position' 33 def parse_bracket(formula): #解析空格中的公式 34 '''解析空格中的公式,并运算出结果''' 35 pattern = r"\(.+\)" 36 m = re.search(pattern,formula) #匹配出所有的括号 ‘3 / 1 - 2 * ( (60-30 * (4-2)) - 4*3/ (6-3*2) )’ 匹配完之后是'( (60-30 * (4-2)) - 4*3/ (6-3*2) )' 37 if m: 38 data_with_brackets = m.group() 39 #print list(data_with_brackets) 40 data_with_brackets = remove_space(list(data_with_brackets)) 41 #print data_with_brackets 42 calc_res = fetch_data_from_bracket(data_with_brackets,data_with_brackets.index(')')) 43 print '\033[32;1mResult:\033[0m', calc_res 44 print calc_res[1],calc_res[2] 45 print data_with_brackets[calc_res[1]:calc_res[2]] 46 del data_with_brackets[calc_res[1]:calc_res[2]] 47 data_with_brackets.insert(calc_res[1], str(calc_res[0])) #replace formula string with caculation result 4 48 return parse_bracket(''.join(data_with_brackets)) #继续处理其它的括号 49 else: #no bracket in formula anymore 50 print '\033[42;1mCaculation result:\033[0m' ,formula 51 52 def caculate_1(formula): # for multiplication and division 53 result = int(formula[0]) # e.g ['4', '/', '2', '*', '5'], loop start from '/' 54 last_operator = None 55 formula = list(formula) 56 nagative_mark = False 57 for index,i in enumerate(formula[1:]): 58 if i.isdigit(): 59 if nagative_mark: 60 i = int('-'+i) 61 nagative_mark = False 62 else: 63 i = int(i) 64 #print '+++>',result,last_operator,i 65 if last_operator == '*': 66 result *= i 67 elif last_operator == '/': 68 try: 69 result /= i 70 except ZeroDivisionError,e: 71 print "\033[31;1mError:%s\033[0m" % e 72 sys.exit() 73 elif i == '-': 74 nagative_mark = True 75 else: 76 last_operator = i 77 78 print '乘除运算结果:' , result 79 return result 80 def caculate_2(data_list,operator_list): 81 '''eg. data_list:['4', 3, 1372, '1'] operator_list:['-', '+', '-']''' 82 data_list = remove_space(data_list) 83 print 'caculater_2:',data_list,operator_list 84 result = int(data_list[0]) 85 for i in data_list[1:]: 86 if operator_list[0] == '+': 87 result += int(i) 88 elif operator_list[0] == '-': 89 result -= int(i) 90 del operator_list[0] 91 92 print 'caculate_2 result:', result 93 return result 94 def parse_operator(formula): 95 print '开始运算公式:',formula 96 formula = formula[1:-1] #remove bracket 97 98 low_priorities = re.findall('[+,-]',''.join(formula)) 99 data_after_removed_low_priorities = re.split('[+,-]', ''.join(formula)) 100 print '去掉加减后的公式列表,先算乘除:',data_after_removed_low_priorities 101 102 for index,i in enumerate(data_after_removed_low_priorities): 103 if i.endswith("*") or i.endswith("/") : 104 data_after_removed_low_priorities[index] += '-' + data_after_removed_low_priorities[index+1] 105 del data_after_removed_low_priorities[index+1] 106 print '---------->handle nagative num:',data_after_removed_low_priorities 107 #计算乘除运算 108 nagative_mark = False 109 110 for index,i in enumerate(data_after_removed_low_priorities): 111 if not i.isdigit(): 112 if len(i.strip()) == 0: 113 nagative_mark = True 114 else:#remove space 115 116 string_to_list = [] 117 if nagative_mark: 118 prior_l = '-' + i[0] # 119 nagative_mark = False 120 else: 121 prior_l = i[0] 122 for l in i[1:] : 123 if l.isdigit(): 124 125 if prior_l.isdigit() or len(prior_l) >1: # two letter should be combined 126 prior_l += l 127 else: 128 prior_l = l 129 else: # an operator * or / 130 131 string_to_list.append(prior_l) 132 string_to_list.append(l) 133 prior_l = l #reset prior_l 134 else: 135 string_to_list.append(prior_l) 136 137 print '--->::', string_to_list 138 calc_res = caculate_1(string_to_list) #乘除运算结果 139 data_after_removed_low_priorities[index] = calc_res 140 #print '--->string to list:',string_to_list 141 #print '+>',index, re.split('[*,/]',i) 142 '''operators = re.findall('[*,/]',i) 143 data = re.split('[*,/]',i) 144 combine_to_one_list = map(None,data,operators) 145 combine_to_one_list =re.split("[\[,\],\(,),'',None]", str(combine_to_one_list)) 146 combine_to_one_list = ''.join(combine_to_one_list).split() 147 print '-->',combine_to_one_list 148 #print operators,data''' 149 #caculate_1(combine_to_one_list) 150 else : 151 if nagative_mark: 152 data_after_removed_low_priorities[index] = '-' + i 153 print '去掉* 和 /后开始运算加减:', data_after_removed_low_priorities,low_priorities 154 #计算加减运算 155 return caculate_2(data_after_removed_low_priorities,low_priorities) 156 #print formula 157 def main(): 158 while True: 159 user_input = raw_input(">>>:").strip() 160 if len(user_input) == 0:continue 161 #parse_bracket(user_input) 162 user_input = '(' + user_input + ')' 163 #parse_bracket(' 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ') 164 parse_bracket(user_input) 165 166 print '\033[43;1mpython计算器运算结果:\033[0m',eval(user_input) 167 if __name__ == '__main__': 168 main()
1 #_*_coding:utf-8_*_ 2 import re 3 def is_symbol(element): 4 res=False 5 symbol=['+','-','*','/','(',')'] 6 if element in symbol: 7 res=True 8 return res 9 10 def priority(top_sym,wait_sym): 11 # print('from the priotry : ',top_sym,wait_sym) 12 level1=['+','-'] 13 level2=['*','/'] 14 level3=['('] 15 level4=[')'] 16 #运算符栈栈顶元素为+- 17 if top_sym in level1: 18 # if wait_sym in level1: 19 # return '>' 20 # elif wait_sym in level2: # top_sym='-' wait_sym='*' 21 # return '<' 22 # elif wait_sym in level3: # top_sym='-' wait_sym='(' 23 # return '<' 24 # elif wait_sym in level4: # top_sym='-' wait_sym=')' 25 # return '>' 26 # else: 27 # return '>' 28 if wait_sym in level2 or wait_sym in level3: 29 return '<' 30 else: 31 return '>' 32 33 #运算符栈栈顶元素为*/ 34 elif top_sym in level2: 35 # if wait_sym in level1:# top_sym='*' wait_sym='+' 36 # return '>' 37 # elif wait_sym in level2:# top_sym='*' wait_sym='*' 38 # return '>' 39 # elif wait_sym in level3:# top_sym='*' wait_sym='(' 40 # return '<' 41 # elif wait_sym in level4:# top_sym='*' wait_sym=')' 42 # return '>' 43 # else: 44 # return '>' 45 if wait_sym in level3: 46 return '<' 47 else: 48 return '>' 49 50 #运算符栈栈顶元素为( 51 elif top_sym in level3: 52 if wait_sym in level4: #右括号)碰到了(,那么左括号应该弹出栈 53 return '=' 54 else: 55 return '<' #只要栈顶元素为(,等待入栈的元素都应该无条件入栈 56 #运算符栈栈顶元素为) 57 58 def calculate(num1,symbol,num2): 59 res=0 60 if symbol == '+': 61 res=num1+num2 62 elif symbol == '-': 63 res=num1-num2 64 elif symbol == '*': 65 res=num1*num2 66 elif symbol == '/': 67 res=num1/num2 68 print('from calculate res is [%s|%s|%s] %s' %(num1,symbol,num2,res)) 69 return res 70 71 def init_action(expression): 72 # print(expression) 73 expression=re.sub(' ','',expression) 74 # print(expression) 75 init_l=[i for i in re.split('(\-\d+\.*\d*)',expression) if i] 76 # print('--->',init_l) 77 expression_l=[] 78 while True: 79 if len(init_l) == 0:break 80 exp=init_l.pop(0) 81 # print('==>',exp) 82 if len(expression_l) == 0 and re.search('^\-\d+\.*\d*$',exp): 83 expression_l.append(exp) 84 continue 85 if len(expression_l) > 0: 86 if re.search('[\+\-\*\/\(]$',expression_l[-1]): 87 expression_l.append(exp) 88 continue 89 90 new_l=[i for i in re.split('([\+\-\*\/\(\)])',exp) if i] 91 expression_l+=new_l 92 # print(expression_l) 93 return expression_l 94 95 def main(expression_l): 96 # print('from in the main',expression_l) 97 number_stack=[] 98 symbol_stack=[] 99 for ele in expression_l: 100 print('-'*20) 101 print('数字栈',number_stack) 102 print('运算符栈',symbol_stack) 103 print('待入栈运算符',ele) 104 105 ret=is_symbol(ele) 106 if not ret: 107 #压入数字栈 108 ele=float(ele) 109 number_stack.append(ele) 110 else: 111 #压入运算符栈 112 while True: 113 if len(symbol_stack) == 0: 114 symbol_stack.append(ele) 115 break 116 res=priority(symbol_stack[-1],ele) 117 118 if res == '<': 119 symbol_stack.append(ele) 120 break 121 elif res == '=': 122 symbol_stack.pop() 123 break 124 elif res == '>': 125 symbol=symbol_stack.pop() 126 num2=number_stack.pop() 127 num1=number_stack.pop() 128 number_stack.append(calculate(num1,symbol,num2)) 129 130 else: 131 symbol=symbol_stack.pop() 132 num2=number_stack.pop() 133 num1=number_stack.pop() 134 number_stack.append(calculate(num1,symbol,num2)) 135 136 return number_stack,symbol_stack 137 138 if __name__ == '__main__': 139 expression='-1 - 2 *((-60+30+(-40/5)*(-9-2*-5/30-7/3*99/4*2998+10/-568/14))-(-4*-3)/(16-3*2))+3' 140 # expression='(1-2*3)-1-2*((-60+30+(-40/5)*(-9-2*-5/30-7/3*99/4*2998+10*568/14))-(-4*-3)/(16-3*2))+3' 141 # expression='-1 -3*( -2+3)' 142 expression_l=init_action(expression) 143 144 # print(expression_l) 145 146 l=main(expression_l) 147 # print('====>',l) 148 print('最终结果是:%s' %l[0][0])