项目 | 内容 |
---|---|
这个作业属于哪个课程 | |
这个作业要求在哪里 | |
这个作业的目标 | 实现一个四则运算式子生成器项目 + 熟悉结对开发项目流程并合作完成 |
1.杂项
1.0 作业所在Github地址
1.1 结对项目成员(学号)
-
张培烽:3118005391
-
杨文伟:3118005390
1.2 需求分析及实现情况
-
使用 -n 参数控制生成题目的个数,例如 Myapp.exe -n 10 将生成10个题目。
使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如 Myapp.exe -r 10
-
实现思路:使用 Python 语言中的 argparse 模块实现命令行传参功能,已实现
-
将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。
-
通过 -r 参数已实现,该值可任意给定,已实现
-
生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2。
-
生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数。
-
已实现
-
每道题目中出现的运算符个数不超过3个。
-
通过 get_operator() 方法已实现
-
生成的题目存入执行程序的当前目录下的Exercises.txt文件,格式如下:
-
四则运算题目1
-
四则运算题目2
……
-
已实现
-
其中真分数在输入输出时采用如下格式,真分数五分之三表示为3/5,真分数二又八分之三表示为2’3/8。
-
利用 Python 中的 Fraction 模块实现
-
在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件,格式如下:
-
答案1
-
答案2
-
已实现
-
程序应能支持一万道题目的生成。
-
已实现
2.主要实现流程
3.实现模块
3.1. Generate_Expression.py(算术表达式生成)
-
get_nums(): 得到随机数列表
-
get_operator(): 得到运算符列表
-
insert_bracket(): 随机插入括号
-
-
get_expression(): 得到运算式
-
num_change_str: 将数字转换为字符串
-
class GenerateExpression(): def get_nums(self, max_value): self.nums = [] self.nums.append(self.get_num(max_value)) for x in range(len(self.operators)): y = self.get_num(max_value) if self.operators[x] == '÷': while y.numerator == 0: y = self.get_num(max_value) self.nums.append(y) if len(self.nums) >= 5: # 当有括号时,不因括号产生多余的数 del self.nums[-2:] def get_operator(self): self.operators = [] operator = ['+', '-', '×', '÷'] for x in range(3): i = random.randint(0, 2) if x != i: self.operators.append(random.choice(operator)) if self.operators == []: self.operators.append(random.choice(operator)) self.insert_bracket() def get_expression(self): self.expression = '' right_bracket_flag = 0 i = 0 for operator in self.operators: if right_bracket_flag or operator == '(': self.expression += operator + ' ' elif operator == ')': self.expression += self.num_change_str(self.nums[i]) + ' ' self.expression += operator + ' ' i += 1 right_bracket_flag = 1 else: self.expression += self.num_change_str(self.nums[i]) + ' ' self.expression += operator + ' ' i += 1 self.expression += self.num_change_str(self.nums[-1]) + ' = ?'
3.2 To_Postfix.py(后缀表达式模块)
为了方便在计算机中进行四则运算,将平常所使用的中缀表达式转换成后缀表达式:即运算符号位于两运算数之后而不是中间,利用此原理编写
To_Postfix.py 模块
-
to_postfix_expression(): 生成逆波兰表达式即后缀表达式
-
numStr2fraction(): 将字符形式的分数转换为 Fraction 形式
class infix2postfix: # 将中缀表达式转换为后缀表达式 def to_postfix_expression(self, expression): # 生成逆波兰表达式即后缀表达式 def numStr2fraction(self, postfix): # 将字符形式的分数转换为 Fraction 形式
3.3 Calculate.py(计算模块)
-
calculate()
-
get_result(): 计算后缀表达式的运算结果
def calculate(num1, num2, operator) def get_result(expression)
3.4 main.py
4. 运行结果
-
生成一万道题目
5. 性能分析
-
基于 -n 10000 -r 20(生成题目与答案文件)
- 由于时间原因,没能展示性能优化过程,这里仅展示最终版运行时间
- 可见get_result()方法消耗时间最长
6.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 40 | 35 |
Estimate | 估计这个任务需要多少时间 | 10 | 8 |
Development | 开发 | 600 | 800 |
Analysis | 需求分析(包括学习新技术) | 60 | 86 |
Design Spec | 生成设计文档 | 30 | 59 |
Design Review | 设计复审 | 20 | 13 |
Coding Standard | 代码规范(为目前的开发制定合适的规范) | 25 | 31 |
Design | 具体设计 | 30 | 45 |
Coding | 具体编码 | 20 | 22 |
Code Review | 代码复审 | 60 | 85 |
Test | 测试(自我测试,修改代码,提交修改) | 50 | 47 |
Reporting | 报告 | 40 | 35 |
Test Repor | 测试报告 | 25 | 30 |
Size Measurement | 测试工作量 | 30 | 55 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 30 | 35 |
Total | 合计 | 1070 | 1386 |
7.项目小结
-
杨文伟:通过这次实践我知道了互相帮助非常重要 注释能免去非常不必要的麻烦 代码规范也能让队友看的更舒服
-
张培烽:
-
项目需求需要梳理清楚,否则后续麻烦
-
与队友需要及时交流沟通,才能使结对项目进行得更加顺利
-
时间安排需要提前规划好,虽然计划总是赶不上变化
-
多打代码,多打代码
-