码迷,mamicode.com
首页 > 编程语言 > 详细

Python之计算器(第四天)

时间:2016-02-18 11:53:05      阅读:379      评论:0      收藏:0      [点我收藏+]

标签:

作业:

     使用正则表达式和递归实现计算器功能。

 实现:

       1、实现带括号的计算

       2、实现指数、加减乘除求余取整等功能


1、实现思路

  1.1 先查找括号,有括号则递归计算括号内的结果。无括号则直接计算表达式

  1.2 使用正则表达式匹配字符串,用计算结果替换计算的表达式。

2、流程图

技术分享

 

3、测试效果

  计算器对于测试输入做了校验。比如输入 ‘-2 - / 3‘ 、 ‘2 + * 3‘ 、 ‘-3 +-‘ 等等

技术分享

技术分享

 

4、源码实现

技术分享
  1 #!/usr/bin/env python3
  2 # -*- coding:utf-8 -*-
  3 # Version:Python3.5.0
  4 import re
  5 
  6 def check_exp(get_input):
  7     ‘‘‘
  8     输入一个表达式,判断是否正确,返回一个去空格的表达式
  9     :param get_input: 获取的表达式
 10     :return: 返回一个去空格的表达式
 11     ‘‘‘
 12     char_set = set((0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
 13                     +, -, *, /, %, //, **, ., (, )))       # 有效表达式的字符集合
 14     # 判断输入的字符合法,输入的表达式字符属于全集char_set为真
 15     if set(get_input).issubset(char_set):
 16         # 输入的表达式是乘号‘*‘、除号‘/‘,百分号‘%‘ 开头的,不合法
 17         if get_input.startswith(*) or get_input.startswith(/) or get_input.startswith(%):
 18             print(\033[31;1m输入的表达式不正确,请重新输入!\033[0m)
 19             return False
 20         # 输入的表达式是乘号‘*‘、除号‘/‘,百分号‘%‘、加号‘+‘、减号‘-‘ 结尾的,不合法
 21         elif (get_input.endswith(*) or get_input.endswith(/) or get_input.endswith(%)
 22                 or get_input.endswith(+) or get_input.endswith(-)):
 23             print(\033[31;1m输入的表达式不正确,请重新输入!\033[0m)
 24             return False
 25         # 输入的表达式中,有两个点号或者加减号后面跟着乘除百分号的,不合法
 26         elif (.. in get_input or +* in get_input or +/ in get_input or +% in get_input
 27                 or -* in get_input or -/ in get_input or -% in get_input):
 28             print(\033[31;1m输入的表达式不正确,请重新输入!\033[0m)
 29             return False
 30         else:
 31             return True
 32     else:
 33         print(\033[31;1m输入的表达式包涵其他字符,无法进行计算,请重新输入!\033[0m)
 34         return False
 35 
 36 def replace_symbol(exp):
 37     ‘‘‘
 38     化简表达式,比如“++-”转换成“-",返回最简表达式
 39     :param exp: 需要化简的表达式
 40     :return:    化简后的表达式
 41     ‘‘‘
 42     # 初始化一个替换字符的列表
 43     replace_char_list = [(+-, -), (-+, -), (++, +), (--, +), (*+, *),
 44                         (/+, /), (%+, %), (//+, //), (**+, **)]
 45     flag = False    # 初始化标识符
 46     count = 0       # 初始化不匹配次数
 47     while not flag:
 48         for i in replace_char_list:
 49             if i[0] in exp:    # 要化简的字符在表达式中,则直接替换
 50                 exp = exp.replace(i[0], i[1])   # 把需要替换的键字符串修改为其值的字符串
 51                 break     # 中断for循环,进行下一次while循环
 52             else:
 53                 count += 1
 54             # 当count等于 len(replace_char_list)时,即 没有需要替换的字符了,退出循环
 55             if count == len(replace_char_list):
 56                 flag = True
 57 
 58         if exp.startswith(+):
 59             exp = exp[1:]   # 除去表达式中开头的加号
 60     return exp
 61 
 62 def parenthesis(exp):
 63     ‘‘‘
 64     运算括号里面的表达式,运算结果替代括号的内容,返回运算结果
 65     :param exp: 计算的表达式
 66     :return: None
 67     ‘‘‘
 68     match = re.search(\(([\+\-\*\/%\/\/\*\*]*\d+\.*\d*){2,}\), exp)  # 匹配括号内的表达式
 69     if match:   # 找到匹配的字符
 70         content = match.group()[1:-1]     # 获取匹配到的表达式,并过滤括号
 71         result = calculate(content)     # 调用计算函数,返回结束结果
 72         print(计算前的表达式:\033[32;1m%s\033[0m % exp)
 73         print(括号中运算结果:\033[33;1m%s=%s\033[0m % (content, result))
 74         replace_content = ( + content + )
 75         exp = exp.replace(replace_content, result)      # 把运算结果替换表达式
 76         exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
 77         print(计算后的表达式:\033[34;1m%s\033[0m\n % exp)
 78         parenthesis(exp)     # 递归执行括号处理
 79     else:
 80         result = calculate(exp)  # 当表达式没有括号时,直接计算表达式结果
 81         print(表达式运算结果:\033[35;1m%s\033[0m % result)
 82 
 83 def power(exp):
 84     ‘‘‘
 85     幂运算,返回运算结果
 86     :param exp: 幂运算的表达式
 87     :return: 计算后的表达式
 88     ‘‘‘
 89     match = re.search(\d+\.?\d*[\*]{2}[\+\-]*\d+\.?\d*, exp)  # 匹配幂运算
 90     if match:   # 找到匹配的字符
 91         content = match.group()     # 获取匹配到的表达式
 92         if len(content.split(**)) > 1:
 93             n1, n2 = content.split(**)
 94             value = float(n1) ** float(n2)
 95             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
 96             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
 97             return power(exp)      # 递归重复匹配
 98         else:
 99             pass
100     else:
101         return exp  # 不匹配到,返回exp
102 
103 def mul_div(exp):
104     ‘‘‘
105     做乘法、除法、取余、取整运算,返回运算结果
106     :param exp: 乘法、除法、取余、取整运算的表达式
107     :return: 计算后的表达式
108     ‘‘‘
109     match = re.search(\d+\.?\d*[\*\/%\/\/]+[\+\-]?\d+\.?\d*, exp)  # 匹配乘、除、取余、取整运算
110     if match:   # 找到匹配的字符
111         content = match.group()     # 获取匹配到的表达式
112         if len(content.split(*)) > 1:
113             n1, n2 = content.split(*)
114             value = float(n1) * float(n2)   # 乘法运算
115             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
116             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
117             return mul_div(exp)
118 
119         elif len(content.split(//)) > 1:
120             n1, n2 = content.split(//)     # 取余运算
121             value = float(n1) // float(n2)
122             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
123             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
124             return mul_div(exp)
125 
126         elif len(content.split(%)) > 1:
127             n1, n2 = content.split(%)     # 除法运算
128             value = float(n1) % float(n2)
129             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
130             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
131             return mul_div(exp)
132 
133         elif len(content.split(/)) > 1:
134             n1, n2 = content.split(/)    # 取整运算
135             value = float(n1) / float(n2)
136             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
137             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
138             return mul_div(exp)
139 
140         else:
141             pass
142     else:
143         return exp  # 不匹配到,返回exp
144 
145 def add_sub(exp):
146     ‘‘‘
147     加法、减法运算,返回运算结果
148     :param exp: 加法、减法运算的表达式
149     :return: 计算后的表达式
150     ‘‘‘
151     match = re.search(\-?\d+\.?\d*[\+\-]+\d+\.?\d*, exp)  # 匹配加法、减法
152     if match:   # 找到匹配的字符
153         content = match.group()     # 获取匹配到的表达式
154         if len(content.split(+)) > 1:
155             n1, n2 = content.split(+)
156             value = float(n1) + float(n2)
157             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
158             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
159             return add_sub(exp)
160 
161         elif len(content.split(-)) > 1:
162             if len(content.split(-)) == 3:    # 被减数是负数的情况
163                 n1, n2 = content.split(-)[1:]     #  过滤分割列表开头的空白字符串
164                 value = float(- + n1) - float(n2)   # 被减数需要添加一个负号
165                 exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
166                 exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
167                 return add_sub(exp)
168             elif len(content.split(-)) == 2:    # 被减数是正数的情况
169                 n1, n2 = content.split(-)     #  直接把两个操作数赋值给对应的变量
170                 value = float(n1) - float(n2)   # 做减法运算
171                 exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
172                 exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
173                 return add_sub(exp)
174             else:
175                 pass
176         else:
177             pass
178     else:
179         return exp  # 不匹配到,返回exp
180 
181 def calculate(exp):
182     ‘‘‘
183     获取一个运算表达式,返回运算结果
184     :param exp: 表达式
185     :return: 运算结果
186     ‘‘‘
187     result = power(exp)         # 执行幂运算,返回运算结果
188     result = mul_div(result)    # 执行乘法、除法、取余、取整运算,返回运算结果
189     result = add_sub(result)    # 执行加法、减法运算,返回运算结果
190     return result
191 
192 if __name__ == __main__:
193     print(\033[31;1m欢迎使用计算器\033[0m.center(100,=))
194     while True:
195         # 计算 s = ‘1-2 *(   (60- 30+(-40.0/5)*(9-2*5 / 3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))‘
196         get_input = input(\n\033[32;1m请输入一个表达式 | 退出(q): \033[0m).strip()
197         get_input = ‘‘.join(re.split(\s+, get_input))    # 除去输入表达式中多余的空格
198         if get_input == ‘‘:     # 空字符,重新输入
199             continue
200         elif get_input == q:
201             print(\033[31;1m退出程序!\033[0m)
202             break
203         elif check_exp(get_input):    # 输入的表达式合法
204             exp = replace_symbol(get_input)     # 化简输入的表达式
205             print(化简后的表达式:\033[33;1m%s\033[0m\n % exp)
206             parenthesis(exp)
207         else:
208             pass
计算器_python35
技术分享
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 # Version:Python2.7.10
  4 import re
  5 
  6 def check_exp(get_input):
  7     ‘‘‘
  8     输入一个表达式,判断是否正确,返回一个去空格的表达式
  9     :param get_input: 获取的表达式
 10     :return: 返回一个去空格的表达式
 11     ‘‘‘
 12     char_set = set((0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
 13                     +, -, *, /, %, //, **, ., (, )))       # 有效表达式的字符集合
 14     # 判断输入的字符合法,输入的表达式字符属于全集char_set为真
 15     if set(get_input).issubset(char_set):
 16         # 输入的表达式是乘号‘*‘、除号‘/‘,百分号‘%‘ 开头的,不合法
 17         if get_input.startswith(*) or get_input.startswith(/) or get_input.startswith(%):
 18             print(u\033[31;1m输入的表达式不正确,请重新输入!\033[0m)
 19             return False
 20         # 输入的表达式是乘号‘*‘、除号‘/‘,百分号‘%‘、加号‘+‘、减号‘-‘ 结尾的,不合法
 21         elif (get_input.endswith(*) or get_input.endswith(/) or get_input.endswith(%)
 22                 or get_input.endswith(+) or get_input.endswith(-)):
 23             print(u\033[31;1m输入的表达式不正确,请重新输入!\033[0m)
 24             return False
 25         # 输入的表达式中,有两个点号或者加减号后面跟着乘除百分号的,不合法
 26         elif (.. in get_input or +* in get_input or +/ in get_input or +% in get_input
 27                 or -* in get_input or -/ in get_input or -% in get_input):
 28             print(u\033[31;1m输入的表达式不正确,请重新输入!\033[0m)
 29             return False
 30         else:
 31             return True
 32     else:
 33         print(u\033[31;1m输入的表达式包涵其他字符,无法进行计算,请重新输入!\033[0m)
 34         return False
 35 
 36 def replace_symbol(exp):
 37     ‘‘‘
 38     化简表达式,比如“++-”转换成“-",返回最简表达式
 39     :param exp: 需要化简的表达式
 40     :return:    化简后的表达式
 41     ‘‘‘
 42     # 初始化一个替换字符的列表
 43     replace_char_list = [(+-, -), (-+, -), (++, +), (--, +), (*+, *),
 44                         (/+, /), (%+, %), (//+, //), (**+, **)]
 45     flag = False    # 初始化标识符
 46     count = 0       # 初始化不匹配次数
 47     while not flag:
 48         for i in replace_char_list:
 49             if i[0] in exp:    # 要化简的字符在表达式中,则直接替换
 50                 exp = exp.replace(i[0], i[1])   # 把需要替换的键字符串修改为其值的字符串
 51                 break     # 中断for循环,进行下一次while循环
 52             else:
 53                 count += 1
 54             # 当count等于 len(replace_char_list)时,即 没有需要替换的字符了,退出循环
 55             if count == len(replace_char_list):
 56                 flag = True
 57 
 58         if exp.startswith(+):
 59             exp = exp[1:]   # 除去表达式中开头的加号
 60     return exp
 61 
 62 def parenthesis(exp):
 63     ‘‘‘
 64     运算括号里面的表达式,运算结果替代括号的内容,返回运算结果
 65     :param exp: 计算的表达式
 66     :return: None
 67     ‘‘‘
 68     match = re.search(\(([\+\-\*\/%\/\/\*\*]*\d+\.*\d*){2,}\), exp)  # 匹配括号内的表达式
 69     if match:   # 找到匹配的字符
 70         content = match.group()[1:-1]     # 获取匹配到的表达式,并过滤括号
 71         result = calculate(content)     # 调用计算函数,返回结束结果
 72         print(u计算前的表达式:\033[32;1m%s\033[0m % exp)
 73         print(u括号中运算结果:\033[33;1m%s=%s\033[0m % (content, result))
 74         replace_content = ( + content + )
 75         exp = exp.replace(replace_content, result)      # 把运算结果替换表达式
 76         exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
 77         print(u计算后的表达式:\033[34;1m%s\033[0m\n % exp)
 78         parenthesis(exp)     # 递归执行括号处理
 79     else:
 80         result = calculate(exp)  # 当表达式没有括号时,直接计算表达式结果
 81         print(u表达式运算结果:\033[35;1m%s\033[0m % result)
 82 
 83 def power(exp):
 84     ‘‘‘
 85     幂运算,返回运算结果
 86     :param exp: 幂运算的表达式
 87     :return: 计算后的表达式
 88     ‘‘‘
 89     match = re.search(\d+\.?\d*[\*]{2}[\+\-]*\d+\.?\d*, exp)  # 匹配幂运算
 90     if match:   # 找到匹配的字符
 91         content = match.group()     # 获取匹配到的表达式
 92         if len(content.split(**)) > 1:
 93             n1, n2 = content.split(**)
 94             value = float(n1) ** float(n2)
 95             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
 96             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
 97             return power(exp)      # 递归重复匹配
 98         else:
 99             pass
100     else:
101         return exp  # 不匹配到,返回exp
102 
103 def mul_div(exp):
104     ‘‘‘
105     做乘法、除法、取余、取整运算,返回运算结果
106     :param exp: 乘法、除法、取余、取整运算的表达式
107     :return: 计算后的表达式
108     ‘‘‘
109     match = re.search(\d+\.?\d*[\*\/%\/\/]+[\+\-]?\d+\.?\d*, exp)  # 匹配乘、除、取余、取整运算
110     if match:   # 找到匹配的字符
111         content = match.group()     # 获取匹配到的表达式
112         if len(content.split(*)) > 1:
113             n1, n2 = content.split(*)
114             value = float(n1) * float(n2)   # 乘法运算
115             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
116             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
117             return mul_div(exp)
118 
119         elif len(content.split(//)) > 1:
120             n1, n2 = content.split(//)     # 取余运算
121             value = float(n1) // float(n2)
122             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
123             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
124             return mul_div(exp)
125 
126         elif len(content.split(%)) > 1:
127             n1, n2 = content.split(%)     # 除法运算
128             value = float(n1) % float(n2)
129             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
130             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
131             return mul_div(exp)
132 
133         elif len(content.split(/)) > 1:
134             n1, n2 = content.split(/)    # 取整运算
135             value = float(n1) / float(n2)
136             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
137             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
138             return mul_div(exp)
139 
140         else:
141             pass
142     else:
143         return exp  # 不匹配到,返回exp
144 
145 def add_sub(exp):
146     ‘‘‘
147     加法、减法运算,返回运算结果
148     :param exp: 加法、减法运算的表达式
149     :return: 计算后的表达式
150     ‘‘‘
151     match = re.search(\-?\d+\.?\d*[\+\-]+\d+\.?\d*, exp)  # 匹配加法、减法
152     if match:   # 找到匹配的字符
153         content = match.group()     # 获取匹配到的表达式
154         if len(content.split(+)) > 1:
155             n1, n2 = content.split(+)
156             value = float(n1) + float(n2)
157             exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
158             exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
159             return add_sub(exp)
160 
161         elif len(content.split(-)) > 1:
162             if len(content.split(-)) == 3:    # 被减数是负数的情况
163                 n1, n2 = content.split(-)[1:]     #  过滤分割列表开头的空白字符串
164                 value = float(- + n1) - float(n2)   # 被减数需要添加一个负号
165                 exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
166                 exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
167                 return add_sub(exp)
168             elif len(content.split(-)) == 2:    # 被减数是正数的情况
169                 n1, n2 = content.split(-)     #  直接把两个操作数赋值给对应的变量
170                 value = float(n1) - float(n2)   # 做减法运算
171                 exp = exp.replace(content, str(value))   # 用计算的结果替换计算的表达式
172                 exp = replace_symbol(exp)   # 检查计算后的表达式是否存在类似 ‘+- ‘等字符,存在的话先替换,后执行
173                 return add_sub(exp)
174             else:
175                 pass
176         else:
177             pass
178     else:
179         return exp  # 不匹配到,返回exp
180 
181 def calculate(exp):
182     ‘‘‘
183     获取一个运算表达式,返回运算结果
184     :param exp: 表达式
185     :return: 运算结果
186     ‘‘‘
187     result = power(exp)         # 执行幂运算,返回运算结果
188     result = mul_div(result)    # 执行乘法、除法、取余、取整运算,返回运算结果
189     result = add_sub(result)    # 执行加法、减法运算,返回运算结果
190     return result
191 
192 if __name__ == __main__:
193     print(u\033[31;1m欢迎使用计算器\033[0m.center(100,=))
194     while True:
195         # 计算 s = ‘1-2 *(   (60- 30+(-40.0/5)*(9-2*5 / 3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))‘
196         get_input = raw_input(u\n\033[32;1m请输入一个表达式 | 退出(q): \033[0m).strip()
197         get_input = ‘‘.join(re.split(\s+, get_input))    # 除去输入表达式中多余的空格
198         if get_input == ‘‘:     # 空字符,重新输入
199             continue
200         elif get_input == q:
201             print(u\033[31;1m退出程序!\033[0m)
202             break
203         elif check_exp(get_input):    # 输入的表达式合法
204             exp = replace_symbol(get_input)     # 化简输入的表达式
205             print(u化简后的表达式:\033[33;1m%s\033[0m\n % exp)
206             parenthesis(exp)
207         else:
208             pass
计算器_python27

Python之计算器(第四天)

标签:

原文地址:http://www.cnblogs.com/suke99/p/5197423.html

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