尝试实现计算器功能,设计制作了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。
在观看了其他人的另类的实现方案后,发现可以使用递归来进行计算,先做个标记,以后补充。