码迷,mamicode.com
首页 > 其他好文 > 详细

计算器

时间:2016-11-29 07:27:52      阅读:1041      评论:0      收藏:0      [点我收藏+]

标签:count   import   [1]   orm   列表   find   tar   not   print   

功能需求:

  • 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致。

  • 实现加减乘除

  • 满足优先级

     

所需知识点:

  1. 流程控制

  2. 函数

  3. 函数递归

  4. 正则表达式

  5. 常用数据类型列表的操作

 

代码逻辑:

技术分享

 

详细代码:

为了方便明白整个逻辑过程,代码中的好多调试信息没有去掉。

  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()

 

计算器

标签:count   import   [1]   orm   列表   find   tar   not   print   

原文地址:http://www.cnblogs.com/wangmo/p/6111828.html

(1)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!