Python实现的复杂的计算器的代码

用Python实现复杂的计算器,可以按照“()”、乘除、加减的优先级进行混合运算。主旨是对正则表达式进行学习。

设计思路:

  1.在计算式中搜索最后一个“(”,再搜索和它匹配的“)”,截取两个括号间的表达式cul。

  2.乘除的优先级高,循环搜索cul内的乘除号,进行计算后进行加减计算,得到结果ans。

  3.用ans替换“(cul)”,重新搜索括号,知道将输入的公式简化成没有括号的四则运算。

  4.对最后的四则运算计算结果。流程图如下:

设计时的注意事项:

  1.在简化计算式过程中,如3*(1-3),简化后为3*-2,在进行乘运算的时候会报错。解决措施为将乘数前的负号移至被乘数前。将算术式更换为-3*2。除法也用相同的方法处理。

  2.在出现“--”或“+-”的时候,可以把“--”替换成“+”,把“+-”替换成“-”。

代码分析:

代码的结构是这样的:


执行文件其实没啥说的!

1 import os,sys
2 BASE_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3 print(BASE_dir)
4 sys.path.append(BASE_dir)
5 from core import main
6 if __name__ == ‘__main__‘:
7     main.run()

calculato.py就是将文件路径添加到环境变量中

 1 import re
 2 def mul(processor):      #乘运算
 3     a = re.search(r"(\d+)?[.]?(\d+)[*]", processor).group()[:-1]
 4     b = re.search(r"[*]\d+[.]?(\d+)?", processor).group()[1:]
 5     ans = float(a) * float(b)
 6     ans = str(ans)
 7     processor_past = re.sub(r"\d+[.]?(\d+)?[*]\d+[.]?(\d+)?", ans, processor, count=1)
 8     return processor_past
 9 def div(processor):        #除运算
10     a = re.search(r"(\d+)?[.]?(\d+)[/]", processor).group()[:-1]
11     b = re.search(r"[/]\d+[.]?(\d+)?", processor).group()[1:]
12     ans = float(a) / float(b)
13     ans = str(ans)
14     processor_past = re.sub(r"\d+[.]?(\d+)?[/]\d+[.]?(\d+)?", ans, processor, count=1)
15     return processor_past
16 def add(processor):      #加运算
17     a=re.search("(\d+)?[.]?(\d+)[+]",processor).group()[:-1]
18     b=re.search("[+]\d+[.]?(\d+)?",processor).group()[1:]
19     ans = float(a)+float(b)
20     ans = str(ans)
21     processor_past = re.sub(r"\d+[.]?(\d+)?[+]\d+[.]?(\d+)?",ans,processor,count=1)
22     return processor_past
23 def sub(processor):      #减运算
24     a=re.search("\d+[.]?(\d+)?[-]",processor).group()[:-1]
25     b=re.search("[-]\d+[.]?(\d+)?",processor).group()[1:]
26     ans = float(a)-float(b)
27     ans = str(ans)
28     processor_past = re.sub(r"\d+[.]?(\d+)?[-]\d+[.]?(\d+)?",ans,processor,count=1)
29     return processor_past

在func.py中定义了运算的方法,由于形参是字符串形式,需将计算结果转换成字符串,然后将结果和算术式替换:如mul("3*2+1)的返回值是“6+1”。

这里还用了字符串的切片方法,删掉第一个值:[1:],删掉最后一个值为[:-1]。

以乘法为例,"*"前必须为数字,被乘数是小数的话还会有小数点和整数位,所以在正则表达式的查询关键字为r“(\d+)?[.]?(\d+)[*]”,所引出字符串后删掉最后的“*”,而“*”后紧跟的是数字,小数点和小数点后的数为非必须字符。用r"[*]\d+[.]?(\d+)?"查找。

在查询关键字时“*"和”+“为转义字符,要在字符串前加”r“

 1 import re
 2 from core import func
 3 def find_brackets(cul):         #将“()”内表达式分析出来
 4     while re.search("[(].+", cul):
 5         cul = re.search("[(].+", cul).group()[1:]
 6     cul = cul[::-1]
 7     while re.search("[)].+", cul):
 8         cul = re.search("[)].+", cul).group()[1:]
 9     cul = cul[::-1]
10     return (cul)
11
12 def change(search,ans,cul):                 #将运算结果和()里的表达式更换
13     search = re.sub("[+]", ‘\+‘,search)
14     search = re.sub("[*]", ‘\*‘,search)
15     cul = re.sub("[(]%s[)]"%search,ans,cul)#在正则表达式中插入变量
16     return cul
17
18 def change_minus(search, ans, before):              # 和move_minus一起移动乘除号后面的负号
19     search = re.sub("[+]", ‘\+‘, search)
20     search = re.sub("[*]", ‘\*‘, search)
21     after = re.sub(search, ans, before)
22     return after
23
24 def move_minus(cul):
25     b = cul
26     if re.search(r"(\d+)?[.]?\d+[*][-](\d+)?[.]?\d+?", cul):
27         a = re.search(r"(\d+)?[.]?\d+[*][-](\d+)?[.]?\d+?", cul).group()
28         c = a
29         a = re.sub("[-]", "", a)
30         a = ‘-‘ + a
31         b = change_minus(c, a, cul)
32     elif re.search(r"(\d+)?[.]?\d+[/][-](\d+)?[.]?\d+?", cul):
33         a = re.search(r"(\d+)?[.]?\d+[/][-](\d+)?[.]?\d+?", cul).group()
34         c = a
35         a = re.sub("[-]", "", a)
36         a = ‘-‘ + a
37         b = change_minus(c, a, cul)
38     return b
39
40
41 def mul_div(str_past):                                              #乘除优先级一致,进行乘除运算
42     ans = str_past
43     while re.search("[\*]|[/]",ans):
44         res = re.search("[/]|[\*]",ans).group()
45         if res == "*":
46             ans = func.mul(ans)
47         elif res =="/":
48             ans = func.div(ans)
49     return ans
50
51 def add_reduce(str_past):                                           #加减优先级一致,进行加减运算
52     ans = str_past
53     ans = re.sub("--","+",ans)
54     ans = re.sub(r"[+][-]","-",ans)
55     while re.search(r"[+]|[-]",ans):
56         if re.match("-",ans):
57             break
58         else:
59             res = re.search(r"[+]|[-]",ans).group()
60             if res == "+":
61                 ans = func.add(ans)
62             elif res =="-":
63                 ans = func.sub(ans)
64     return ans
65
66 def cul(str):
67     cul = str
68     ans = str
69     while re.search("[(]",cul):
70         cul = re.sub("--", "+", cul)
71         cul = re.sub(r"[+][-]", "-", cul)
72         cul_1 = find_brackets(cul)
73         ans = mul_div(cul_1)
74         ans = add_reduce(ans)
75         ans = change(cul_1,ans,cul)
76         cul = ans
77         cul = move_minus(cul)
78     ans = move_minus(ans)
79     ans = mul_div(ans)
80     ans = add_reduce(ans)
81     return ans

calcu.py定义了整个计算的流程。

cul()中不断索引括号,将索引出的算术式计算后用结论替代。每简化一轮后检查乘除号后是否有负号的状态。

乘除法的优先级比加减高,可以把乘除的运算放在一起,

while re.search("[\*]|[/]",ans):

用这个方法可以从左到右循环搜索算术式内的乘除运算。

 1 import re
 2 import os,sys
 3 from core import calcu,func.log
 4 def run():
 5     print("欢迎使用计算器!!!")
 6     while True:
 7         cul = input("请输入计算公式:")
 8         if cul == "exit":
 9             print("退出计算器!")
10             break
11         elif re.findall("[(]", cul).__len__() != re.findall("[)]", cul).__len__():
12             print("括号不匹配!")
13         elif re.search("[(]|[)]",cul):
14             print("请使用英文符号!")
15         elif re.search("[a-z]|[A-Z]",cul):
16             print("请输入数字!")
17         else:
18             ans = calcu.cul(cul)
19             print(ans)
20             log.logger(cul,ans)

main.py调用了整个算式的计算过程,并对输入的公式进行了一些纠错措施并在每次计算后将计算式和结论存储在日志中。

1 import time
2 def logger(cul,ans):
3     fp = open("logger.txt",‘a+‘,encoding="UTF-8")
4     now = time.time()
5     fp.write("%s     %s=%s\n"%(now,cul,ans))
6     fp.close()

log.py就是将每次运算的公式和结论存储在日志中。

存在的问题:日志文件应存储在log路径下,但是现在每次执行完会在bin路径下生成新日志文件并进行存储操作。还在想办法改进中!

原文地址:https://www.cnblogs.com/yinsedeyinse/p/10010325.html

时间: 2024-10-06 10:53:05

Python实现的复杂的计算器的代码的相关文章

python之路-利用索引切片功能做一个简易的两个未知数的加法计算器,代码如下:

python之路-利用索引切片功能做一个简易的两个未知数的加法计算器,代码如下: #content = input('请输入内容:'),如用户输入:5 +9或 5 + 9 等,然后进行分割再进行计算. content = input('>>>').strip() #content 等于所输入的内容,strip:删除字符串左右两边的空格. index = content.find('+') ''' content内容中的两边的空格都删除了,但中间还有,现在我们只需要定位已知内容是加法,两边

python之实现ftp上传下载代码(含错误处理)

# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之实现ftp上传下载代码(含错误处理) #http://www.cnblogs.com/kaituorensheng/p/4480512.html#_label2 import ftplib import socket import os def ftpconnect(ftp_info): try: ftp = ftplib.FTP(ftp_info[0]) except (socket.er

Javascript 实现简单计算器实例代码

Javascript 实现简单计算器实例代码 这篇文章主要介绍了Javascript 实现简单计算器实例代码的相关资料,需要的朋友可以参考下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

[转] 三种Python下载url并保存文件的代码

原文 三种Python下载url并保存文件的代码 利用程序自己编写下载文件挺有意思的. Python中最流行的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib从ftp站点下载文件.此外Python还提供了另外一种方法requests. 来看看三种方法是如何来下载zip文件的: import urllib import urllib2 import requests url = 'http://www.blog.pythonlibrary.org/wp-c

Head First Python(如何向PYPI发布你的代码)学习笔记

Head  First  Python(如何向PYPI发布你的代码) 当我们编写好的一个完美的python程序或者一个好的项目程序时,那时作为程序猿的我们是如何的激动啊,在那激动的时刻如何与他人分享我们胜利的果实呢?看这里~哈哈 为了共享这个模块,需要将它发布出去,在python中,所谓发布(distribution)是指一个文件集合,将这些文件联合到一起允许你构建,打包和发布你的模块,一旦发布,就可以 把模块先安装到你的本地python上,还有就是可以把你的代码上传到PYPI与全世界共享你的代

让c像python一样可以在命令行写代码并且编译

在你亲爱的.bashrc/.zshrc中添加 ###C###go_libs="-lm"go_flags="-g -Wall -include allheads.h -O3"alias go_c="c99 -xc '-' $go_libs $go_flags" 然后再/usr/include目录下新建一个allheads.h文件 在里面添加你想要添加的头文件,比如 #include <stdio.h>#include <math.

python字符串格式化输出及相关操作代码举例

字符串的格式化 Python 支持格式化字符串的输出 .尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中.在   Python 中,字符串格式化使用与 C 中 sprintf 函数一样的语法. 在python中格式化输出字符串通用的形式为: 格式标记字符串 % 要输出的值组 其中,左边部分的"格式标记字符串"可以完全和c中的一致.右边的"值组"如果有两个及以上的值则需要用小括号括起来,中间用逗号隔开. 重点来看左

Use My Python,Send Your Mail(十来行代码)

人生苦短,我用python,最近实习一直在用工作,因为我做的工作涉及到海量数据,程序跑下来用上代理,一个月可能也跑不完,但是我快要回去考试两周,作为一个强迫症的coder,我必须要得知我的程序怎么了!!!所以我让我的程序成功执行一段时间,但是我又是非常"懒惰"的人(其实优秀的程序员都要很"懒惰"呢!坚决写简洁的代码,如果可以,越短越好,所以前短时间写了个160行的py 2048.),看了好多版本,看得我很郁闷呢-最后经过整理,得出这十行,送你! import smt

python写的简单有效的爬虫代码

python写的简单有效的爬虫代码 by 伍雪颖 import re import urllib def getHtml(url): html = urllib.urlopen(url) scode = html.read() return scode def getImage(source): reg = r'src="(.*?\.jpg)"' imgre = re.compile(reg) images = re.findall(imgre,source) x = 0 for i