尝试实现计算器功能,设计制作了2天,打了大概170行代码,最后功能是能够实现,但是依旧存在重大bug——不能对负数进行计算。

虽然可以添加大量if语句就可实现对于负数的判断来进行计算,但是显得代码不高效,所以先将代码放上来,以后在进行修改。

import re
# 四则运算
def yunsuan(jisuan):
'''
对传入的值进行四则运算
:param jisuan:传输一个只包含一个符号两个数值的值
:return: 返回一个经过四则运算的值
'''
# 抽取数值
number = re.findall("\d+", jisuan)
# 抽取符号
fuhao = re.findall('[^\d]', jisuan)
if fuhao[0] == "/":
jieguo = int(number[0]) / int(number[1])
jieguo = str(jieguo)
if fuhao[0] == "*":
jieguo = int(number[0]) * int(number[1])
jieguo = str(jieguo)
if fuhao[0] == "+":
jieguo = int(number[0]) + int(number[1])
jieguo = str(jieguo)
if fuhao[0] == "-":
jieguo = int(number[0]) - int(number[1])
jieguo = str(jieguo)
return jieguo
# 公式运算
def chouqu(txt):
'''
该模块主要是计算无括号时的算式,主要调用四则运算模块,然后将其运算结果替换其算式
:param txt: 没有括号的算式
:return: 返回输入这条算式的结果
'''
switch1 = True
# 循环传入
while switch1:
# 检测是否含有运算符,无则退出
fuhao_count = re.search("[\*|/]+|[+|-]+", txt)
if fuhao_count == None:
switch1 = False
break
# 提取只含一个运算符号的公式
jisuan = re.search("[\d]+[\*|/][\d]+", txt)
if jisuan == None:
jisuan = re.search("[\d]+[+|-][\d]+", txt)
jisuan = str(jisuan.group())
zhi = yunsuan(jisuan)
else:
jisuan = str(jisuan.group())
zhi = yunsuan(jisuan)
zhi = str(zhi)
# 对符号进行无意义化处理
fuhao = re.search("[\*|/]+|[+|-]+", jisuan)
fuhao = str(fuhao.group())
if fuhao == "/":
jisuan = re.sub("\/", "\/", jisuan)
if fuhao[0] == "*":
jisuan = re.sub("\*", "\*", jisuan)
if fuhao[0] == "+":
jisuan = re.sub("\+", "\+", jisuan)
if fuhao[0] == "-":
jisuan = re.sub("\-", "\-", jisuan)
# 将对应的运算结果替换该运算公式
txt = re.sub(jisuan, zhi, txt)
return txt
cuowu = 0
switch = False
txt = input("请输入你想要计算的算式")
# 清除空格
txt = re.sub(" ", "", txt)
zuokuohao_count = re.findall("\(", txt)
youkuohao_count = re.findall("\)", txt)
# 判断括号数量
if youkuohao_count.__len__() == zuokuohao_count.__len__():
switch = True
else:
print("该算式缺少部分括号,请补齐")
# 判断是否连用符号
txt_fuhao = re.findall("[^\d\(\w\)]+", txt)
for i in txt_fuhao:
if len(i) > 1:
cuowu = 1
switch = False
if cuowu == 1:
print("该算式符号重叠 请重新输入")
while switch:
# 判断是否含有括号
txt1 = re.search("\([^\(\)]+\)", txt)
if txt1 == None:
switch = False
break
txt1 = str(txt1.group())
# 取出括号内字符串
number = str(re.findall("[^\(\)]+", txt1)[0])
# 调用公式运算模块,计算出结果
number = chouqu(number)
# 将提取的括号算式符号无意义化
zhuanhuan = re.sub("\*", "\*", txt1)
zhuanhuan = re.sub("\+", "\+", zhuanhuan)
zhuanhuan = re.sub("\(", "\(", zhuanhuan)
txt1 = re.sub("\)", "\)", zhuanhuan)
# 将括号内计算出来的值赋值到最初总算式中,并继续进行循环
txt = re.sub(txt1, number, txt)
end_jieguo = chouqu(txt)
print(end_jieguo)

实现计算器的过程,我的想法主要是将传入的算式进行分解,首先创建一个只针对一个符号两边的数值的运算函数,称为“四则运算”函数,该函数的返回值为结果,然后代替该运算算式。

之后再将该“四则运算”函数嵌套进一个针对一整条算式且不包含“()”的运算函数当中去,称为“提取”函数,主要功能是将一整条算式不断进行四则运算,最后导出这条算式的值。

最后我就是用了一个while循环来解决最后一步,针对“()”的运算,将括号内的算式提取之后再放入“提取”函数当中去,得出该算式结果,然后替换掉该括号内的算式,然后使用一个针对括号判断的if语句来控制while循环,不断循环去除括号后就只剩下一条算式,代入“提取”函数即可。

依旧存在无法对负数进行计算的bug。

在观看了其他人的另类的实现方案后,发现可以使用递归来进行计算,先做个标记,以后补充。