请用python3编写一个计算器的控制台程序_二、软件工程慕课第一章作业题——编写一个计算器...
一、题目描述
请用Python3编写一个计算器的控制台程序,支持加减乘除、乘方、括号、小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算。
二、输入描述
数字包括"0123456789",小数点为".",运算符包括:加("+")、减("-")、乘("*")、除("/")、乘方("^",注:不是**!)、括号("()")
需要从命令行参数读入输入,例如提交文件为main.py,可以用python3 main.py "1+2-3+4"的方式进行调用,Java程序也是类似的,如果你的程序需要通过键盘输入,那么是不符合要求的,例如python使用input()来等待用户输入,这会因为自动评测时不会有用户输入所以不会有任何结果。
输入需要支持空格,即 python3 main.py "1 + 2 - 3 + 4" 也需要程序能够正确给出结果,Java程序也是类似的
所有测试用例中参与运算的非零运算数的绝对值范围保证在 10^9-10^(-10) 之内, 应该输出运算结果时非零运算结果绝对值也保证在该范围内
三、输出描述
数字需要支持小数点,输出结果取10位有效数字,有效数字位数不足时不能补0
对于不在输入描述内的输入,输出INPUT ERROR
对于格式不合法(例如括号不匹配等)的输入,输出 FORMAT ERROR
对于不符合运算符接收的参数范围(例如除0等)的输入,输出VALUE ERROR
对于2、3、4的情况,输出即可,不能抛出异常
同时满足2、3、4中多个条件时,以序号小的为准
四、样例
输入: 1 + 2 - 3 + 4
输出: 4
输入: 1 + 2 - 3 + 1 / 3
输出: 0.3333333333
输入: 1 + + 2
输出: FORMAT ERROR
输入: 1 / 0
输出: VALUE ERROR
输入: a + 1
输出: INPUT ERROR
五、思路总结
python中有一个eval函数可以直接进行算式的计算,但我估计这个作业的目的是让我们自己实现,故先对式子进行处理,式子的处理查阅了网上的一些方法,觉得自己能理解和写出来的就是利用正则表达式将字符串形式的算式变成列表,然后进行处理
1 importre2
3 defconversionFormula(formula):4
5 format_list = re.findall('[\w\.]+|\(|\+|\-|\*|\/|\^|\)',formula)6
7 return format_list
这里要用到re库的方法对接收的字符串进行列表的转换,例如接受[1+2*3],转换后为[ '1', '+', '2', '*', '3' ],转换完成后就是对式子进行分析,最重要的就是对括号的处理,我采取的方法是对列表进行遍历,找到最内层的括号,然后对里面的式子进行求解,然后将此括号及中间的算式替换成答案,然后递归进行新式子的求解。下面贴出的方法可以将将列表里的括号及括号里的式子处理完毕后进行返回,格式依然是列表
1 defremove_bracket(formula):2 leftBracket =03 count = 0 #用遍历列表进行计数
4
5 for i informula:6 if i == '(': #记录最内侧左括号的位置
7
8 leftBracket=count9
10 elif i == ')':11
12 smallestFomula = formula[leftBracket+1:count] #提取最内层括号里式子
13 smallestFomulaAnswer = calculator(smallestFomula) #调用calculator方法进行计算
14
15 if smallestFomulaAnswer < 0: #更新式子,对去括号后的+-,--情况进行分析
16 if formula[leftBracket-1] == '-':17 formula[leftBracket-1] = '+'
18 temp =formula[:leftBracket]19 temp.append(str(abs(smallestFomulaAnswer)))20 formula = temp+formula[count+1:]21
22 elif formula[leftBracket-1] == '+':23 formula[leftBracket-1] = '-'
24 temp =formula[:leftBracket]25 temp.append(str(abs(smallestFomulaAnswer)))26 formula = temp+formula[count+1:]27
28 else:29 temp =formula[:leftBracket]30 temp.append(str(smallestFomulaAnswer))31 formula = temp+formula[count+1:]32
33 else:34 temp =formula[:leftBracket]35 temp.append(str(smallestFomulaAnswer))36 formula = temp+formula[count+1:]37
38 return remove_bracket(formula) #递归,进行新式子的去括号分析
39
40 count+=1
41
42 return formula #返回无括号的最终式子
还有一部分就是对括号内的式子进行计算
1 defcalculator(formula):2 count =03 for i in formula: #先处理乘方、乘除
4 if i == '^':5 formula[count-1]=str(float(formula[count-1])**float(formula[count+1]))6 del(formula[count])7 del(formula[count])8 returncalculator(formula)9
10 elif i == '*':11 formula[count-1]=str(float(formula[count-1])*float(formula[count+1]))12 del(formula[count])13 del(formula[count])14 returncalculator(formula)15
16 elif i == '/':17 formula[count-1]=str(float(formula[count-1])/float(formula[count+1]))18 del(formula[count])19 del(formula[count])20 returncalculator(formula)21
22 count+=1
23
24 count=025
26 if formula[0]=='-': #处理第一个字符是’-’的情况
27 formula[1]=formula[0]+formula[1]28 del(formula[0])29
30 for i in formula: #处理加减
31 if i == '+':32 formula[count-1]=str(float(formula[count-1])+float(formula[count+1]))33 del(formula[count])34 del(formula[count])35 returncalculator(formula)36
37 elif i == '-':38 formula[count-1]=str(float(formula[count-1])-float(formula[count+1]))39 del(formula[count])40 del(formula[count])41 returncalculator(formula)42
43 count+=1
44
45 return float(formula[0]) 返回float型的运算结果
最后是在主函数里对上述两个方法进行调用
1 if __name__ == '__main__':2
3 formula=input('请输入算式:')4 formula="".join(formula.split())5 formula =eq_format(formula)6 formula =remove_bracket(formula)7 answer =calculator(formula)8 print(answer)
六、完善
到上述部分,大体功能就完成了,下面进行一些修修补补,要求里需要对空格、格式不对、补0等问题进行处理主要修改的有conversionFormula和主函数一些地方,下面贴出代码
1 defconversionFormula(formula):2
3 format_list = re.findall('[\w\.]+|\(|\+|\-|\*|\/|\^|\)',formula)4 switch =05 switch2=06 count=07 for i informat_list:8 if i == '(' or i == ')': #进行括号符号的判断
9 switch2+=1
10
11 for i informat_list:12 if i == '+' or i == '-' or i == '*' or i == '/' or i == '^':#进行加减乘除乘方符号的判断
13 switch =1
14 break
15 if switch != 1:16 print('INPUT ERROR')17 return 'ERROR'
18 for i in format_list: #进行一些错误的判断
19 if i == '+' or i == '-' or i == '*' or i == '/':20 if format_list[count-1] == '+' or format_list[count-1] == '-' or\21 format_list[count-1] == '*' or format_list[count-1] == '/' or\22 format_list[count+1] == '+' or format_list[count+1] == '-' or\23 format_list[count+1] == '*' or format_list[count+1] == '/':24 print('FORMAT ERROR')25 return 'ERROR'
26 elif i == '/' and format_list[count+1] == '0':27
28 print('VALUE ERROR')29 return 'ERROR'
30 elif i.isalpha() ==True:31 print('INPUT ERROR')32 return 'ERROR'
33 count+=1
34 if switch2 % 2 !=0:35 print('FORMAT ERROR')36 return 'ERROR'
37
38 return format_list
1 if __name__ == '__main__':2
3 formula=input('输入:')4 formula="".join(shizi.split()) #空格处理
5 formula =conversionFormula(formula)6
7 if formula != 'ERROR': #错误判断
8 formula =remove_bracket(formula)9 answer =calculator(formula)10 if float(answer).is_integer() ==True:11 answer=int(answer)12 else:13 answer=format(answer,'.10f') #空格补0,不足位数不补0
14 answer=float(str(answer).rstrip('0'))15 print(answer)16 else:17 a=1
到此还有一个从命令行输入参数的要求,故将主函数中输入参数部分作修改
1 if __name__ == '__main__':2
3 formula="".join(sys.argv[1:])4 formula =conversionFormula(formula)5
6 if formula != 'ERROR': #错误判断
7 formula =remove_bracket(formula)8 answer =calculator(formula)9 if float(answer).is_integer() ==True:10 answer=int(answer)11 else:12 answer=format(answer,'.10f') #空格补0,不足位数不补0
13 answer=float(str(answer).rstrip('0'))14 print(answer)15 else:16 a=1
这里在调试的时候遇到一个问题,题目要求乘方按照2^2的形式输入,我在dos中输入时报错:
查了下资料dos要这样使用特殊字符需要加上转义符^,即输入 2^^2:
或者”2^2"
至此,题目所有要求已经实现,但未经过大量测试,所以存在的问题还需要进一步的研究,下面贴出完整代码
1 importre2 importsys3
4
5 defconversionFormula(formula):6
7 format_list = re.findall('[\w\.]+|\(|\+|\-|\*|\/|\^|\)',formula)8 switch =09 switch2=010 count=011 for i informat_list:12 if i == '(' or i == ')':13 switch2+=1
14
15 for i informat_list:16 if i == '+' or i == '-' or i == '*' or i == '/' or i == '^':17 switch =1
18 break
19 if switch != 1:20 print('INPUT ERROR')21 return 'ERROR'
22 for i informat_list:23 if i == '+' or i == '-' or i == '*' or i == '/':24 if format_list[count-1] == '+' or format_list[count-1] == '-' or\25 format_list[count-1] == '*' or format_list[count-1] == '/' or\26 format_list[count+1] == '+' or format_list[count+1] == '-' or\27 format_list[count+1] == '*' or format_list[count+1] == '/':28 print('FORMAT ERROR')29 return 'ERROR'
30 elif i == '/' and format_list[count+1] == '0':31
32 print('VALUE ERROR')33 return 'ERROR'
34 elif i.isalpha() ==True:35 print('INPUT ERROR')36 return 'ERROR'
37 count+=1
38 if switch2 % 2 !=0:39 print('FORMAT ERROR')40 return 'ERROR'
41
42 returnformat_list43
44
45 defcalculator(formula):46 count =047 for i informula:48
49 if i == '^':50 formula[count-1]=str(float(formula[count-1])**float(formula[count+1]))51 del(formula[count])52 del(formula[count])53 returncalculator(formula)54
55 if i == '*':56 formula[count-1]=str(float(formula[count-1])*float(formula[count+1]))57 del(formula[count])58 del(formula[count])59 returncalculator(formula)60
61 elif i == '/':62 formula[count-1]=str(float(formula[count-1])/float(formula[count+1]))63 del(formula[count])64 del(formula[count])65 returncalculator(formula)66
67 count+=1
68
69 count=070
71 if formula[0]=='-':72 formula[1]=formula[0]+formula[1]73 del(formula[0])74
75 for i informula:76
77 if i == '+':78 formula[count-1]=str(float(formula[count-1])+float(formula[count+1]))79 del(formula[count])80 del(formula[count])81 returncalculator(formula)82
83 elif i == '-':84 formula[count-1]=str(float(formula[count-1])-float(formula[count+1]))85 del(formula[count])86 del(formula[count])87 returncalculator(formula)88
89 count+=1
90
91 returnfloat(formula[0])92
93 defremove_bracket(formula):94 leftBracket =095 count = 0 #用遍历列表进行计数
96
97 for i informula:98 if i == '(':99
100 leftBracket=count101 elif i == ')':102
103 smallestFomula = formula[leftBracket+1:count]104 smallestFomulaAnswer =calculator(smallestFomula)105 if smallestFomulaAnswer <0:106 if formula[leftBracket-1] == '-':107 formula[leftBracket-1] = '+'
108 temp =formula[:leftBracket]109 temp.append(str(abs(smallestFomulaAnswer)))110 formula = temp+formula[count+1:]111
112 elif formula[leftBracket-1] == '+':113 formula[leftBracket-1] = '-'
114 temp =formula[:leftBracket]115 temp.append(str(abs(smallestFomulaAnswer)))116 formula = temp+formula[count+1:]117
118 else:119 temp =formula[:leftBracket]120 temp.append(str(smallestFomulaAnswer))121 formula = temp+formula[count+1:]122 else:123 temp =formula[:leftBracket]124 temp.append(str(smallestFomulaAnswer))125 formula = temp+formula[count+1:]126
127 returnremove_bracket(formula)128 count+=1
129
130 returnformula131
132 if __name__ == '__main__':133
134 formula="".join(sys.argv[1:])135 formula =conversionFormula(formula)136
137 if formula != 'ERROR':138 formula =remove_bracket(formula)139 answer =calculator(formula)140 if float(answer).is_integer() ==True:141 answer=int(answer)142 else:143 answer=format(answer,'.10f')144 answer=float(str(answer).rstrip('0'))145 print(answer)146 else:147 a=1
程序运行如下
请用python3编写一个计算器的控制台程序_二、软件工程慕课第一章作业题——编写一个计算器...相关推荐
- C语言编程练习 2.编写人得票统计程序。设有3个候选人,每次输入一个得票候选人的名字,不考虑弃权情况,要求最后输出各个候选人的得票结果(参加投票人数由程序运行时输入)。
题目完整描述 编写人得票统计程序.设有3个候选人,每次输入一个得票候选人的名字,不考虑弃权情况,要求最后输出各个候选人的得票结果(参加投票人数由程序运行时输入). 这是一道关于 一维数组做函数参数 的 ...
- SpringBoot | 第一章:第一个SpringBoot应用
2019独角兽企业重金招聘Python工程师标准>>> SpringBoot | 第一章:第一个SpringBoot应用 springboot简单介绍 概述 随着动态语言的流行(Ru ...
- java编写某计算器控制台程序_计算器 - 进阶的憨狗 - 博客园
源起 最近在看程杰著作的<大话设计模式>,全书以小菜和大鸟对话的形势,由浅入深的讲解程序的设计思想,影射出一个个设计模式.我之前虽然也使用过一些设计模式,但没有系统的学习.整理.总结,现从 ...
- java如何给一个链表定义和传值_如何在CUDA中为Transformer编写一个PyTorch自定义层...
如今,深度学习模型处于持续的演进中,它们正变得庞大而复杂.研究者们通常通过组合现有的 TensorFlow 或 PyTorch 操作符来发现新的架构.然而,有时候,我们可能需要通过自定义的操作符来实现 ...
- java写一个android程序_【Android开发笔记】3.编写第一个Android程序
前言 上一节我们通过一个Demo熟悉了Eclipse的基本使用.如何在模拟器和手机中运行以及如何打包成APK,但没具体编写代码,相信很多同学已经按耐不住了吧,这一节我们会动手编写代码来熟悉Androi ...
- java质数和合数的程序_《java项目实训》课程设计计算器.doc
<java项目实训>课程设计计算器.doc 课程设计报告课程名称JAVA项目实训课程设计设计名称基于JAVA计算器的设计与实现学生学号学生姓名学生学号学生姓名学生学号学生姓名学生学号学生姓 ...
- java完成一个学生信息调查程序_利用Java设计一个简单的学生信息管理程序
利用Java设计一个简单的控制台学生信息管理程序 此程序可作为课设的参考,其中信息存储于文件中. 创建了学生类Student,用于存储学号等的信息.创建StudentFunction类,用于实现诸如学 ...
- 一个完整的嵌入式程序_放下偏见,原来嵌入式程序员如此“妖娆”!
感兴趣的小伙伴可以来我的Java交流群,可以获取免费的学习资料 828 697 593 对Java技术,架构技术感兴趣的同学,欢迎加群,一起学习,相互讨论. 竟然都看到最后了,给小编点个关注吧,小编还 ...
- vs怎么建java的控制台程序_像VS一样简单的打包“控制台”程序
对于我一个不了解JAVA,没有相关生态圈的C#er, 自己要研究Scala真是困难重重,尤其在项目构建上真是感觉半瓶子醋难以入门. 一个VS控制台程序,build之后甚至不需要了解 ms build就 ...
最新文章
- 【并发编程】创建线程的四种方式
- 前端那些事之原生js实现jquery常用方法
- 聊聊高并发(二十)解析java.util.concurrent各个组件(二) 12个原子变量相关类
- 基于混沌的图像置乱加密算法及matlab的实现,基于混沌的图像置乱加密算法及MATLAB的实现...
- java $ class_java文件编译后额外生成的$1.class是怎么一回事
- node连接--MySQL
- 一个人想生存发展具备3大关键
- eeglab导出图片
- SAP HANA2.0 EXPRESS 下载及安装详细教程---第一部分
- android 第三方 im,Android基于环信SDK开发IM即时聊天
- 渗透测试-红队从资产收集到打点
- [转](1条消息) 前端必知:针对高分辨率屏幕的样式优化(转载请删除括号里的内容)
- THREE.JS 与其他库的对比
- 7、Spring AOP使用
- 为什么给黑洞拍照需要这么长时间?
- 【毒鸡汤】英译毒鸡汤——人生已经如此艰难,何不落井下石
- ElasticSearch 学习笔记:Multi Search
- 对于学习新技术的思考
- Java——命令jps、jstat、jmap、jstack、jhat、jinfo
- 无法安装32位版本的Office,因为在您的PC上找到了以下64位程序