2018102993小学四则运算练习软件项目报告
此作业的要求参见链接的任务三个人任务:https://mooc1-1.chaoxing.com/mycourse/studentstudy?chapterId=131597991&courseId=89792820&clazzid=787341&enc=c382f8d8d1497e335c16e41e067b8848
任务1:
尝试按照《构建之法》第2章中2.3所述PSP流程,独立完成一个3到5个运算符的四则运算练习的命令行软件开发。
软件基本功能要求如下:
-
程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。
-
每个练习题至少要包含2种运算符。不得出现负数与非整数。
-
练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
-
当程序接收的参数为4时,以下为一个输出文件示例。
2018010203 13+17-1=29 11*15-5=160 3+10+4-16=1 15÷5+3-2=4
源码地址:https://coding.net/u/Ruidxr/p/four_arithmetic_operation/git
需求分析
1.能够随机生成0-100的数字和3-5个运算符;
2.能够将随机数和运算符组成可计算的算式并计算出正确的结果;
3.能够控制生成的题目数。
4.能够将生成的题目和答案按要求格式写入文件“result.txt”中。
功能设计
基本功能:按输入的数字生成相应数量的四则运算题目并写入文件。
扩展功能:暂无。
设计实现
1.栈
2.生成随机的算式
3.将算式转为逆波兰表达式
4.计算逆波兰表达式的值
5.将表达式和运行结果写入文件
算法详解
1.栈
设计为一个类,包括栈初始化、入栈、出栈和计算栈的长度。
2.生成随机的算式
使用random生成随机数、控制运算符的个数随机、生成随机运算符,将生成的数值和符号组成算式。
3.将算式转为逆波兰表达式
在python中设定四则运算符号的优先级,
cal = {"+": 1, "-": 1, "*": 2, "÷": 2}
借助栈实现生成后缀表达式。
4.计算逆波兰表达式的值
根据3转化的栈中的逆波兰表达式出栈计算。
5.将表达式和运行结果写入文件
文件读写,设计好写入文件的内容及其格式。
测试运行
运行截图如下:
比较独特的或满意的代码片段
以下贴出几个函数,函数功能见函数名称。
1 class PyStack(object): #自定义栈 2 3 def __init__(self, initSize = 20, incSize = 10): 4 self.initSize = incSize 5 self.incSize = incSize 6 self.stackList = [] 7 self.top = self.bottom = 0 8 9 def push(self, ele): 10 if self.top-self.bottom >= self.initSize: 11 self.incSize += self.initSize 12 self.stackList.append(ele) 13 self.top += 1 14 15 def pop(self): 16 if self.top-self.bottom > 0: 17 self.top -= 1 18 ret = self.stackList.pop() 19 return ret 20 else: 21 return None 22 23 def len(self): 24 return self.top-self.bottom
1 def create_equation(): 2 eq = [] 3 sign = random.randint(3, 5) #运算符的个数 4 for i in range(sign): 5 eq.append(random.randint(1, 100)) 6 eq.append(operator[random.randint(0, 3)]) 7 eq.append(random.randint(1, 100)) 8 return eq
1 def reverse_polish(equation): 2 result = [] 3 c = [] 4 slist = [i for i in equation] 5 for item in slist: 6 if item in range(0, 100): 7 result.append(item) 8 elif not c and item in cal.keys(): 9 c.append(item) 10 continue 11 elif c and item in cal.keys(): 12 for x in range(c.__len__()): 13 z = c[-1] 14 temp = cal[z] if z in cal else cal1[z] 15 if temp >= cal[item]: 16 result.append(c.pop()) 17 else: 18 c.append(item) 19 break 20 if not c: 21 c.append(item) 22 elif item == ")": 23 for x in range(c.__len__()): 24 if c[-1] == "(": 25 c.pop() 26 break 27 else: 28 result.append(c.pop()) 29 elif item == "(": 30 c.append(item) 31 for x in range(c.__len__()): 32 result.append(c.pop()) 33 return result
1 def calculate(re_equation): # 计算逆波兰表达式 2 stack = PyStack() 3 sumEnd = 0 4 5 if len(re_equation) is 0: 6 return sumEnd 7 for i in re_equation: 8 if i in range(0, 100): 9 stack.push(float(i)) 10 elif '+' is i: 11 a = stack.pop() 12 b = stack.pop() 13 stack.push(b + a) 14 elif '-' is i: 15 a = stack.pop() 16 b = stack.pop() 17 stack.push(b - a) 18 elif '*' is i: 19 a = stack.pop() 20 b = stack.pop() 21 stack.push(b * a) 22 elif '÷' is i: 23 a = stack.pop() 24 b = stack.pop() 25 if a == 0: 26 return False #print('%d/%d分子不能为0' % (b, a)) 27 else: 28 stack.push(b / a) 29 return stack.pop()
PSP
PSP | 任务内容 | 计划共完成需要的时间(min) | 实际完成需要的时间(min) |
Planning | 计划 | 30 | 26 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 30 | 26 |
Development | 开发 | 570 | 740 |
Analysis | 需求分析 (包括学习新技术) | 120 | 158 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 47 |
Coding | 具体编码 | 300 | 412 |
Code Review | 代码复审 | 30 | 44 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 79 |
经验分享
本次编程任务使用了python语言,对生成后缀表达式、后缀表达式的计算以及栈的使用有了深刻的实践性的理解。在编程前,做好需求分析很重要,准确的分析了需求才能知道自己要实现什么,才能有一个明确的实现目标。良好的代码规范也很重要,能够增加程序的可读性和规范性。具体编码过程中,努力解决遇到的一个个细节问题,然后最终看到实现功能是很有成就感的。
作者:段小胖 本文版权归作者和博客园共有,欢迎转载。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出,以免更多的人被误导。 |