结对项目
结对项目
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience/homework/13479 |
| 这个作业的目标 | 实现一个自动生成小学四则运算题目的命令行程序 |
| github连接: | LancyPluto/3123004789 at 结对项目 |
| 成员一 | 蓝毅 3123004789 |
| 成员二 | 杨腾竣 3123004809 |
一、psp表格如下
| Process Stages | Process Stages (中文) | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 20 | 25 |
| · Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
| Development | 开发 | 420 | 360 |
| · Analysis | · 需求分析 (包括学习新技术) | 120 | 120 |
| · Design Spec | · 生成设计文档 | 15 | 20 |
| · Design Review | · 设计复审 | 100 | 120 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 90 | 90 |
| · Design | · 具体设计 | 60 | 90 |
| · Coding | · 具体编码 | 400 | 420 |
| · Code Review | · 代码复审 | 90 | 100 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 120 | 120 |
| Reporting | 报告 | 80 | 100 |
| · Test Report | · 测试报告 | 40 | 70 |
| · Size Measurement | · 计算工作量 | 20 | 20 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 10 |
| · 合计 | 1625 | 1675 |
二、计算模块接口的设计与实现过程
2.1 程序整体结构
2.1.1 核心模块
| 模块名称 | 主要函数 | 功能职责 |
|---|---|---|
| 命令行解析模块 | main() |
解析 -n -r(生成模式)和 -e -a(批改模式)参数,作为程序入口 |
| 表达式构建模块 | generate_expr(max_ops, r) random_number(r) |
随机生成合法的四则运算表达式树(含自然数/真分数),控制运算符数、不产生负数、不非法除法 |
| 运算与格式化模块 | eval()(各类 Expr) serialize() frac_to_str() |
计算表达式结果,输出标准格式(整数、真分数、带分数) |
| 去重校验模块 | canonicalize(expr) |
将表达式转换为唯一结构字符串(对 commutative 运算排序)用于避免题目重复 |
| 题目生成模块 | generate_unique_exercises(count, r) write_files() |
批量生成不重复题目与答案,并写入 Exercises.txt 和 Answers.txt |
| 答案解析模块 | parse_fraction(s) |
将字符串格式的整数/真分数/带分数解析为 Fraction 对象 |
| 题目求值模块 | evaluate_exercise(expr_line) |
将题目字符串解析并求出正确答案(支持混合数替换、×÷转换) |
| 批改统计模块 | grade(ex_file, ans_file) |
对比答案,统计对错编号,生成 Grade.txt(Correct/ Wrong 格式) |
2.2 算法核心
2.2.1 核心思想
Ⅰ. 题目生成算法
思想核心:随机生成表达式树 + 约束条件筛选 + 去重
(1)表达式树生成
- 通过递归构建表达式树(
Expr类层次结构)。 - 节点类型包括:
Num(叶节点,表示自然数或真分数)BinOp(中间节点,表示 +, −, ×, ÷ 运算)
(2)运算约束条件
a - b时必须满足a ≥ b(防止负数)a ÷ b时结果必须在(0, 1)之间(确保是真分数)- 运算符数量 ≤ 3
- 数值范围由参数
-r控制
(3)去重规则(核心难点)
-
对于
+和×,题目视为可交换:a + b≡b + a -
使用
canonicalize(expr)生成表达式的规范化字符串:
- 同构结构 + commutative 运算排序
- 如
(+:N:2,N:3)与(+:N:3,N:2)→ 统一为同一键值
-
以哈希表 (
set) 去重。
(4)输出格式化
- 使用
serialize()生成表达式字符串(含括号) - 使用
frac_to_str()输出真分数 / 带分数格式 - 同步生成
Exercises.txt与Answers.txt
Ⅱ. 批改算法
思想核心:计算真实答案 + 比对学生答案 + 输出统计
(1)解析题目并计算正确答案
- 替换符号:
× → *÷ → /2'3/5 → (2 + 3/5)
- 使用
Fraction精确计算避免浮点误差。
(2)解析学生答案
- 将输入字符串(整数、真分数、带分数)解析成
Fraction对象。
(3)比较结果
- 若
Fraction值相等 → 正确 - 否则 → 错误
- 记录题号(从 1 开始)
2.2 算法流程图

三、计算模块性能优化
| 优化方向 | 具体措施 | 改进思路 |
|---|---|---|
| 去重机制 | 将表达式结构的 canonical key 缓存在 set 中,使用 tuple 表示结构 |
避免字符串拼接与重复生成 |
| 表达式生成 | 使用迭代控制运算深度而非纯递归 | 减少函数调用开销 |
| Fraction 计算 | 延迟求值,仅在最终输出时化简 | 避免中间节点重复计算 |
| I/O 写入 | 采用一次性批量写入 | 减少文件 I/O 系统调用次数 |

四、代码说明
二元操作类 BinOp:
- 这个类也继承自
Expr,用于表示带有两个操作数和一个操作符的二元运算(如a + b)。它包含一个运算符(op)和两个操作数(left和right)。eval()方法根据运算符对两个操作数执行运算,serialize()方法将其格式化为字符串表示。

递归生成表达式 generate_expr:
- 这个函数递归生成包含max_ops运算符的数学表达式。它通过递归调用build()函数来生成运算表达式,最终返回一个二元运算对象(BinOp)。表达式中的操作符有加、减、乘、除,且会遵循一些约束:
- 减法不能生成负数。
- 除法的结果必须是一个真分数(即结果在 0 和 1 之间)。

五、测试运行
命令行输入:
python test.py -n 10 -r 10
生成题目:

答案:

结果:

经验算,结果全部正确,说明程序运行正常。
六、项目小结
1.项目概述
本项目实现了一个小学四则运算题自动生成与批改程序,包括:
- 随机生成题目(整数、分数、带分数)
- 自动计算答案
- 去重与格式化输出
- 批改答案并输出统计结果
通过命令行参数可选择生成模式或批改模式。
2.项目成果
功能完整:题目生成、答案计算、批改一体化
结构清晰:面向对象设计,模块独立
细节完善:避免负数、控制除法真分数、格式化输出
3.问题与教训
输入与异常处理不够完善
难度控制单一
文件名与路径较固定
启示:提前统一接口与数据格式;早期测试可避免集中调试。

浙公网安备 33010602011771号