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
stack
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
create_equation
 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
RPF
 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()
calculate

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语言,对生成后缀表达式、后缀表达式的计算以及栈的使用有了深刻的实践性的理解。在编程前,做好需求分析很重要,准确的分析了需求才能知道自己要实现什么,才能有一个明确的实现目标。良好的代码规范也很重要,能够增加程序的可读性和规范性。具体编码过程中,努力解决遇到的一个个细节问题,然后最终看到实现功能是很有成就感的。

posted @ 2018-10-07 15:12  段晓睿  阅读(365)  评论(0编辑  收藏  举报