软件工程第三次作业-结对项目

个人项目

项目 内容
这个作业属于哪个课程 [软件工程](首页 - 计科23级12班 - 广东工业大学 - 班级博客 - 博客园)
这个作业要求在哪里 [作业要求](结对项目 - 作业 - 计科23级12班 - 班级博客 - 博客园)
这个作业的目标 训练个人项目软件开发能力,学会使用性能测试工具和实现单元测试优化程勋

GitHub代码仓库 :lei)


作者:唐雷3123004154 袁梓轩3123004591

PSP2表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 10 15
Estimate 估计这个任务需要多少时间 60 90
Development 开发 250 270
Analysis 需求分析 (包括学习新技术) 30 40
Design Spec 生成技术文档 30 30
Design Review 设计复审 50 60
Coding Standard 代码规范 (为目前的开发制定合适的规范) 10 10
Design 具体设计 30 40
Coding 具体编码 150 250
Code Review 代码复审 30 30
Test 测试(自我测试,修改代码,提交修改) 20 30
Reporting 报告 60 100
Test Repor 测试报告 20 10
Size Measurement 计算工作量 60 45
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 40 30

📘 小学四则运算题目自动生成与判分系统设计报告

一、代码组织

本项目的核心功能包括:

  • 随机生成四则运算表达式;
  • 自动计算表达式的结果;
  • 验证表达式合法性;
  • 对用户答案进行判分。

类设计

Expr 类
用于构建表达式树。每个节点代表一个运算单元:

  • 叶子节点存储数值(Fraction 对象);
  • 非叶子节点包含运算符(+ - * /)以及左右子树。

主要方法:

  • eval():递归计算表达式的数值;
  • to_string():将表达式转为可读字符串;
  • canonical():生成规范化字符串,用于表达式去重。

函数组织

函数名 功能说明
random_leaf(r) 生成随机整数或真分数,范围受参数 r 限制
generate_expression(op_count, r) 递归生成表达式树,自动验证合法性
format_fraction_display(fr) 将分数格式化为整数、真分数或带分数形式
generate_problems(n, r) 批量生成表达式及对应答案,并确保不重复
evaluate_expression_str(expr_line) 将字符串形式的表达式解析并求值
grade(exercise_file, answer_file) 对比题目与答案文件,输出正确与错误题号
write_exercises_answers(problems) 将生成的题目和答案写入文件

模块关系概述

  • Expr 是核心数据结构,定义表达式树节点;
  • generate_expression 使用 Expr 生成随机表达式;
  • evaluate_expression_str 用于解析字符串表达式;
  • grade 调用解析函数对答案进行比对;
  • format_fraction_displaycanonical 用于输出标准化表达式。

结构图如下:

random_leaf ─┐
              │
generate_expression ──> Expr ──> eval / to_string / canonical
              │
generate_problems ────> write_exercises_answers
              │
              └──> grade ──> evaluate_expression_str

二、关键函数流程图

以下是 generate_expression 的核心流程:

开始
  |
  v
生成随机叶子(整数或分数)
  |
  v
随机选择操作符(+ - * /)
  |
  v
组合左右子树并计算结果
  |
  v
验证操作是否合法:
    - 减法结果非负
    - 除法分母非零且结果非整数
  |
  v
若合法 -> 构造 Expr 节点
若非法 -> 重新生成
  |
  v
返回完整表达式树
结束

三、算法关键与创新点

  1. 表达式树结构设计
    使用 Expr 类表示表达式,既能递归计算,又能控制打印格式,避免歧义。

  2. 合法性约束检查

    • 减法结果不得为负数;
    • 除法不得出现整数结果(保持分数特性);
    • 不允许除以零;
    • 所有中间结果非负。
  3. 去重机制(Canonical 表示)
    对于交换律运算符(+*),将子表达式规范化排序,避免生成重复题。

  4. 带分数与真分数输出
    使用 format_fraction_display 将结果统一为整数、真分数或带分数,输出符合小学格式。


四、项目关键代码与解释

1️⃣ 表达式生成

def generate_expression(op_count, r, max_tries=200):
    for attempt in range(max_tries):
        leaves_vals = [random_leaf(r) for _ in range(op_count + 1)]
        leaf_nodes = [Expr(value=v) for v in leaves_vals]
        nodes = leaf_nodes[:]
        for _ in range(op_count):
            i = random.randint(0, len(nodes) - 2)
            left = nodes[i]
            right = nodes[i+1]
            op = random.choice(OPS)
            new_node = Expr(op=op, left=left, right=right)
            # 合法性验证
            aval, bval = left.eval(), right.eval()
            if op == '-' and aval < bval: break
            if op == '/' and (bval == 0 or aval / bval == int(aval / bval)): break
            nodes[i:i+2] = [new_node]
        if len(nodes) == 1:
            return nodes[0]
    return None

功能:递归生成带有约束的表达式树。
关键点

  • 通过多次尝试生成合法表达式;
  • 使用随机数控制结构多样性;
  • 确保表达式无负数、无零除。

2️⃣ 表达式求值

def evaluate_expression_str(expr_line):
    expr_line = expr_line.strip()
    if expr_line.endswith('='):
        expr_line = expr_line[:-1].strip()
    tokens = tokenize(expr_line)
    rpn = shunting_yard(tokens)
    return eval_rpn(rpn)

功能:将字符串表达式解析为逆波兰式(RPN),再计算结果。
关键点

  • 支持整数、真分数、带分数;
  • 兼容括号与多操作符优先级;
  • 使用分数计算确保精度。

五、测试用例与结果验证

以下展示部分自动生成的样例题目与对应答案(节选自 Exercises.txtAnswers.txt):

题目 计算结果
4'1/2 * (6 * 1/7) = 3'6/7
(8 + (7/9 + 8)) - 1/2 = 16'5/18
(4'8/9 * 1/2) / 2/3 = 3'2/3
7 + 1'1/2 = 8'1/2
6 - 5/6 = 5'1/6
0 * 5/8 = 0
1 + 1 = 2
1/2 * 9 = 4'1/2
(5'1/2 - 1/4) / 8 = 21/32
2'6/7 + 3 = 5'6/7

正确性验证:

  • 所有结果均由 Fraction 自动约分;
  • 与手工计算结果对比一致;
  • 判分模块可正确识别学生答案格式差异。

六、结对开发经验总结

  1. 鼓励试错
    “发现问题比快速推进更有价值”。例如在表达式生成时,初版出现除零错误,通过约束函数逐步修正。

  2. 主动沟通与复盘
    每次修改算法逻辑(如去重规则、混合分数生成)后,双方及时复盘输出效果。

  3. 任务分工清晰
    一人负责表达式生成与校验,另一人负责解析与判分模块,实现高效协作。

  4. 调试技巧
    在生成表达式树时,增加打印与断点输出树结构,帮助定位逻辑错误。


posted @ 2025-10-18 10:59  leitang  阅读(58)  评论(0)    收藏  举报