软件工程第三次作业-结对项目
| 这个作业属于哪个课程 | 班级的链接 |
|---|---|
| 这个作业要求在哪里 | 作业的链接 |
| 这个作业的目标 | <结对实现一个自动生成小学四则运算题目的命令行程序> |
一、成员信息和作业github链接
| 成员姓名 | 学号 |
|---|---|
| 戴清 | 3223004598 |
| 颜宏宇 | 3223004733 |
作业github的链接: 作业github的链接
二、PSP表格
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 30 | 40 |
| · Estimate | · 估计这个任务需要多少时间 | 10 | 5 |
| Development | 开发 | 100 | 110 |
| · Analysis | · 需求分析 (包括学习新技术) | 30 | 45 |
| · Design Spec | · 生成设计文档 | 35 | 40 |
| · Design Review | · 设计复审 | 15 | 30 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 40 |
| · Design | · 具体设计 | 30 | 35 |
| · Coding | · 具体编码 | 180 | 200 |
| · Code Review | · 代码复审 | 40 | 45 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 50 | 55 |
| Reporting | 报告 | 70 | 80 |
| · Test Repor | · 测试报告 | 45 | 60 |
| · Size Measurement | · 计算工作量 | 20 | 20 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 15 |
| · 合计 | 705 | 820 |
三、效能分析
3.1改进程序性能的改进的思路,
(一)优化 “题目去重” 逻辑
原问题:最初采用 “列表存储所有标准化表达式,新题目生成后遍历列表对比” 的方式,当题目数量超过 5000 道时,单次对比耗时超 0.5 秒,1 万道题总生成时间达 12 分钟,严重不符合需求。
改进方案:改用 “哈希表存储标准化表达式”,key 为标准化后的表达式字符串,value 为布尔值。新题目生成后,直接通过 key 查询哈希表,单次查询耗时降至 0.001 秒以内。
(二) 优化 “文件写入” 方式
原问题:最初采用 “先将所有题目 / 答案存入列表,全部生成后一次性写入文件” 的方式,1 万道题的文本数据占用内存超 80MB,程序运行中出现明显卡顿,甚至偶发内存溢出提示。
改进方案:采用 “分批次写入” 策略,每生成 1000 道题 / 答案,就调用文件写入接口将数据写入磁盘,同时清空临时存储的列表,释放内存。
(三)简化 “括号生成” 判断
原问题:最初括号生成逻辑会对所有运算符数量≥1 的题目进行 “是否添加括号” 的复杂判断,即使运算符数量为 1,也会执行判断流程,增加无效计算耗时。
改进方案:添加前置判断 —— 仅当运算符数量≥2 时,才执行括号生成逻辑;运算符数量为 1 时,直接跳过括号判断,减少冗余计算。
3.2展示性能分析的图
生成题目过程的性能数据图:

批改过程的性能图:

3.3说明你程序中消耗最大的函数
根据性能分析图,程序中消耗最大的函数是 generate_expression 函数
四、设计实现过程
4.1代码组织。
(一)此程序模板文件及核心类,函数及它们的功能如下:
| 模块文件 | 主要功能 | 核心类 / 函数 |
|---|---|---|
| main.py | 命令行交互与流程控制 | main()函数 |
| generator.py | 四则运算题目生成 | ExerciseGenerator类 |
| validator.py | 答案批改与结果生成 | AnswerValidator类 |
| calculator.py | 表达式解析与计算 | ExpressionCalculator类 |
| utils.py | 分数格式化与验证工具 | format_fraction()等函数 |
(二)类与函数关系
依赖关系:
main.py 依赖 ExerciseGenerator和 AnswerValidator;
ExerciseGenerator 和 AnswerValidator 均依赖 ExpressionCalculator;
分数处理功能通过 utils.py 工具函数共享。
核心类职责:
ExerciseGenerator:生成不重复、符合规则的四则运算表达式;
AnswerValidator:对比学生答案与正确答案,生成批改结果;
ExpressionCalculator:安全解析并计算表达式。
4.2关键函数流程图?
(一)generate_number 函数流程图
(二)safe_eval 函数流程图
(三)split_by_operator 函数流程图
五、代码说明
5.1项目关键代码,并解释思路与注释说明

此关键函数思路为:1. 使用递归方法构建表达式树;2. 通过深度控制限制表达式复杂度;3. 验证各种约束条件(减法、除法、范围等);4. 确保生成的题目符合小学数学要求

此关键函数思路为:1. 30%概率生成分数,70%概率生成自然数;2. 分数生成时,30%概率生成带分数;3. 确保所有数值都在指定范围内

此关键函数思路为:1. 去除空格简化处理;2. 递归处理表达式,对+和×的操作数排序;3. 处理括号嵌套情况;4. 通过标准化实现表达式去重
六、测试运行
6.1共享你对程序进行测试的至少10个测试用例

6.2为什么能确定程序是正确的。
(一)程序使用Python的Fraction类进行所有分数计算,这确保了数学运算的精确性,避免了浮点数计算中的精度问题,所有计算都基于分数运算,保证了结果的准确性。
(二)程序严格遵循所有题目生成约束条件,数值范围控制确保所有生成的数字都在指定范围内,自然数范围是0到range_num-1,分数分母范围是2到range_num,分子范围是1到分母-1。
(三)程序经过了全面的边界条件测试,包括:数值边界测试;减法边界测试;除法边界测试;运算符数量测试,确保生成表达式时计算的结果与后续验证时计算的结果完全一致。
七、测试运行项目小结。
7.1结对项目总结成败得失,分享经验,总结教训。
(一)成功之处
1.程序实现了题目生成、答案计算、对错判定三大核心功能,支持 -n、-r、-e/-a,且严格遵循真分数格式、无负数计算、无重复题目等规则;
2.采用模块化设计,将题目生成”“分数运算”“文件读写”“判题统计” 拆分为独立函数 / 类,降低耦合度,后续修改单一功能时无需改动整体逻辑;
3.针对分母为 0、减法结果为负、除法非真分数等异常情况,通过前置判断和回溯机制规避,确保生成的题目符合数学逻辑;判题功能也能准确识别真分数的不同书写格式。
(二)待改进之处
1.题目生成效率待提升,当 -n=10000 且 -r=100 时,因需频繁判断题目是否重复,程序运行时间较长;
2.括号生成逻辑比较单一。
(三)经验与教训
1.拿到需求后,先进行需求拆解,然后再逐个突破,避免因需求混乱导致做完一步不知道下一步要做什么。
2.应该要根据两人擅长的方面先对任务进行分工,每天同步 1 次进度,遇到卡点时共同调试,避免发生有一方不知道要做什么的情况。
3.在开发每个模块后,都先写测试用例验证,再集成到主程序,避免后期大规模排查 BUG 。
7.2结对感受,以及两个人对彼此结对中的闪光点或建议的分享。
(一)结对感受
本次结对开发打破了单人开发的思维局限,在设计每个板块的时候可以互相交流意见,找到更好的方法,在完成任务的过程中两人可以互相补充,及时查漏补缺,遇到瓶颈也可以一起讨论找到解决方法,比独自开发时得到的方案更优。
(二)评价
两人在本次项目都很认真。双方都会严格按照题目要求检查要求,主动解决细节问题以此来提升结果准确性。双方都参与了测试模块,设计了多组针对性测试用例来验证分数运算逻辑是否满足题目要求。双方都认真编写代码,保证程序代码的规范性。

浙公网安备 33010602011771号