结对项目

项目 内容
这个作业属于哪个课程 软件工程
这个作业要求在哪里 作业要求
这个作业的目标 学习项目协作开发过程

GitHUb代码仓库:👨💻 [https://github.com/xiu-ye/zuoye2]

作者:莫晓淇3223004213 张荣辉31232004162

PSP:

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

1.代码组织

计算模块的核心功能是生成数学表达式、计算表达式的值以及验证表达式的合法性。代码组织如下:

    • Number:封装整数和分数,提供分数的简化、字符串表示和分数转换功能。
    • ExpressionNode:表示表达式树的节点,支持叶子节点(数字)和非叶子节点(操作符和左右子树)。
  • 函数

    • generate_expression:递归生成随机的数学表达式树。
    • evaluate:递归计算表达式树的值。
    • is_valid:验证表达式树的合法性。
    • validate_operation:验证特定操作符的合法性(如减法和除法的约束)。
    • generate_number:生成随机数(整数或分数)。
    • canonical_form:将表达式树转换为规范形式,避免重复表达式。
    • format_expression:将表达式树格式化为带括号和空格的字符串。

类与函数的关系

  • NumberExpressionNode 是数据结构的核心,分别表示数字和表达式节点。
  • generate_expression 使用 ExpressionNode 构建表达式树,并调用 generate_number 生成随机数。
  • evaluateis_valid 依赖于 ExpressionNode 的结构,递归计算或验证表达式。
  • validate_operationgenerate_expression 的辅助函数,确保生成的表达式合法。
  • canonical_formformat_expression 用于表达式的标准化和输出。

2.关键函数流程图

以下是 generate_expression 的流程图:

开始
  |
  v
生成随机数(概率 0.3 或达到最大操作数) -> 返回叶子节点
  |
  v
选择随机操作符(+、-、*、/)
  |
  v
递归生成左子树
  |
  v
递归生成右子树
  |
  v
验证操作合法性(validate_operation) -> 如果非法,重新生成
  |
  v
返回非叶子节点
结束

算法的关键与独到之处

  • 递归生成表达式:通过递归随机生成表达式树,确保表达式的多样性和复杂性。
  • 规范形式:通过 canonical_form 避免生成重复的表达式。
  • 合法性验证:在生成过程中实时验证减法和除法的合法性,确保表达式可计算。

3. 项目关键代码与解释

生成表达式

def generate_expression(max_ops, max_num, current_ops=0):
    if current_ops > max_ops:
        return None

    if random.random() < 0.3 or current_ops == max_ops:
        return ExpressionNode(value=generate_number(max_num))

    op = random.choice(['+', '-', '*', '/'])
    left = generate_expression(max_ops, max_num, current_ops + 1)
    right = generate_expression(max_ops, max_num, current_ops + 1)

    if not validate_operation(left, right, op, max_num):
        return generate_expression(max_ops, max_num, current_ops)

    return ExpressionNode(left=left, op=op, right=right)
  • 功能:递归生成随机表达式树。
  • 关键点
    • 通过 random.random() 控制生成叶子节点的概率。
    • 使用 validate_operation 确保操作合法性。

计算表达式值

def evaluate(node):
    if node.is_leaf():
        return node.value.to_fraction()

    left = evaluate(node.left)
    right = evaluate(node.right)

    return {
        '+': lambda a, b: a + b,
        '-': lambda a, b: a - b,
        '*': lambda a, b: a * b,
        '/': lambda a, b: a / b
    }[node.op](left, right)
  • 功能:递归计算表达式树的值。
  • 关键点
    • 使用字典映射操作符到对应的计算函数。
    • 递归计算左右子树的值。

4. 测试用例

以下是 10 个测试用例及其说明:

测试用例 预期结果 说明
1 + 2 3 简单加法
3 - 2 1 简单减法
2 * 3 6 简单乘法
6 / 2 3 简单除法
1/2 + 1/2 1 分数加法
1/2 - 1/3 1/6 分数减法
1/2 * 2/3 1/3 分数乘法
1/2 / 1/4 2 分数除法
1 + 2 * 3 7 运算符优先级
(1 + 2) * 3 9 括号优先级

正确性验证

  • 通过手工计算验证每个测试用例的预期结果。
  • 使用 evaluate 函数计算结果并与预期结果对比。

5. 结对项目经验总结

  • 鼓励试错:“发现问题比快速推进更有价值”
  • 主动表达思路:边写代码边解释意图,如“这里用递归处理树结构,因为层级不确定”。
  • 及时提问与反馈:发现问题时直接指出
  • 避免长时间沉默:若卡壳,可共同画流程图或伪代码理清逻辑。
posted @ 2025-03-22 18:49  辉辉辉——  阅读(39)  评论(0)    收藏  举报