清明小长假结束,来,鼓足精神,继续学习。
今儿一起看怎么用Python做一个简单的计算器。
编写计算器这个程序,需要熟悉re模块。不熟悉的回头看进阶第七课。熟悉了re就能很容易编写出代码,否则无解。
现在还不会写这个程序,转发一个吧:
https://www.cnblogs.com/Wxtrkbc/p/5453349.html,这个写的详细,且行数多。介绍完毕后,后面还有另一个例子,较为简洁。供大家参考。
一、功能分析
用户输入一个类似这样 3*( 4+ 50 )-(( 100 + 40 )*5/2- 3*2* 2/4+9)*((( 3 + 4)-4)-4) 这样的表达式,假设表达式里面除了包含空格、'+'、'-'、'*'、'/'和括号再无其他特殊符号,然后自己动手写代码解析其中的表达式,实现加减乘除,最后得出的结果与真实的计算机所算的结果必须一致。
二、所需的知识点
字符串的处理
正则表达式的运用
函数递归
三、程序实现流程分析
用正则表达式处理字符串,只提取其中的数字和运算符,并转换成列表
编写一个函数,处理没有括号的基本运算的基本表达式
再写一个函数递归处理带有括号的函数,先计算最内部括号中的表达式, 然后将最内部的括号替换为计算后的结果, 在递归外部一层的, 最后返回的就是所需的结果
四、具体实现过程
1.正则表达式处理用户输入字符串
这里我不会讲正则表达式具体的用法,要将的话都可以讲一本书了,我只讲本文用到的正则表达式。根据需求,我们需要提取出用户输入字符串中的数字和运算符到一个列表中,而空格将会被忽略掉,假设用户输入的表达式是 expression,我们可以写出下面的代码:
import re
expression='(( 100 + 40 )*5/2- 3*2* 2/4+9)*((( 3 + 4)-4)-4)'
l=re.findall('([\d\.]+|/|-|\+|\*)',expression)
print(l) #['100', '+', '40', '*', '5', '/', '2', '-', '3', '*', '2', '*', '2', '/', '4', '+', '9', '*', '3', '+', '4', '-', '4', '-', '4']
首先我们先看一下 findall 的用法,findall可以匹配所有符合规律的内容,返回包含结果的列表。'([\d\.]+|/|-|\+|\*)'是匹配规则,这里\d表示匹配一个数字,\.表示将.转义成数字上小数点 . ,不然在正则表达式里 . 可以匹配除了换行符以外的任意字符。[\d\.]+表示可以匹配至少由一个数字、或者小数点 . 组成的字符串,比如说,这里既可以匹配到100,也可以匹配到100.11。|/|-|\+|\* 表示匹配到+或-或*或/,()表示一组,这里意思是如果匹配到数字或者+或者-或者*或者/其中任意一个的话,就将其作为一组,然后添加到列表中去。
2.不含括号的表达式的计算
为了后面迭代算出有括号的表达式,我们先写一个没有括号的表达式,比如说像这样一个表达式 '100.5+40*5/2-3*2*2/4+9',对于这样的表达式我们肯定是计算乘除,在计算加减,计算一个最小计算单元后,再将结果放回列表中不断循环,直到算出整个不带括号的表达式,实现的代码如下:
import re
expression= '100.5+40*5/2-3*2*2/4+9'
l = re.findall('([\d\.]+|/|-|\+|\*)',expression)
print(100.5+40*5/2-3*2*2/4+9) # 206.5
def multdiv(l,x): #定义最小的乘除运算单元,l是列表,x代表*或/
a = l.index(x) #首先获取乘除运算符的位置
if x=='*': #如果是*则执行乘法运算
k = float(l[a - 1]) * float(l[a + 1]) #获取乘法运算的结果,比如k=3*2
else:
k = float(l[a - 1]) / float(l[a + 1])
del l[a - 1], l[a - 1], l[a - 1] #删除掉列表里刚做运算的三个元素,比如,3 * 2
l.insert(a - 1, str(k)) #将刚计算的结果插入到列表中然后执行下一次计算
return l
def fun(s):
sum=0
while 1: #先将乘除运算计算完,在计算加减
if '*' in l and '/' not in l: #先判断,如果只有*的话,先计算 *
multdiv(l, '*')
elif '*' not in l and '/' in l: #如果只有 /的话,先计算 /
multdiv(l, '/')
elif '*' in l and '/' in l: #如果既有 / 也有 *的话,先获取他们的下标,
a = l.index('*') #根据下标判断先执行哪个
b = l.index('/')
if a < b:
multdiv(l, '*')
else:
multdiv(l, '/')
else: #当上面的乘除计算完之后,就可以计算加减了
if l[0]==