• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
xiao2145
博客园    首页    新随笔    联系   管理    订阅  订阅

结对项目

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-12
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/homework/13221
这个作业的目标 结对合作完成项目
两位同学的姓名 许莹柔,学号:3222004684 肖晓霞,学号:3222004853
Github项目地址 https://github.com/9650X/exercise/tree/main/exercise

1.PSP表格

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

2.效能分析

功能一: 生成题目和答案

我们采用cProfile进行性能分析,情况如下图所示,花费时间为2h。在性能上,在代码中耗时最多的函数为generate_and_write_expressions,平均调用耗时为0.162s,改进的思路为:(1)当表达式的结果为负数时,不用完全重新生成所有的操作数和运算符;(2)在生成操作数和运算符之前,可以预计可能的结果范围,以减少生成负数结果的可能性。
性能分析结果展示如下:

功能二:校对答案

我们采用cProfile进行性能分析,情况如下图所示,花费时间为3h,在性能上,在代码中耗时最多的函数为write_grades,平均调用耗时为0.117s,改进的思路为:通过设置open函数的buffering参数减少磁盘I/O操作的次数。
性能分析结果展示如下:

3.设计实现过程

功能一:类和函数的设计

代码包含1个类:
ArithmeticExpressionGenerator 类:这个类将包含所有生成算术表达式和答案的逻辑。
代码包含7个函数:
generate_number 方法:用于生成自然数或真分数。
generate_true_fraction 方法:用于生成真分数。
generate_operator 方法:用于随机选择运算符。
calculate_expression 方法:用于计算表达式的值。
format_number 方法:用于格式化数字。
generate_expression 方法:用于生成算术表达式。
main 方法:作为程序的入口点,用于解析命令行参数并生成表达式。
这个设计将所有的函数封装在一个类中,使得代码更加模块化和易于维护。同时,通过命令行参数来控制生成表达式的数量和操作数的范围。

功能二:类和函数的设计

代码包含7个函数:
init:构造函数,用于初始化类实例,并接受练习文件和答案文件的路径。
parse_arguments:用于解析命令行参数。
parse_fraction:用于解析分数字符串并返回分数对象。
read_files:用于从指定文件中读取练习和答案。
calculate_expression:用于计算表达式的结果。
check_answers:用于检查答案是否正确。
main:主方法,用于执行整个检查流程
函数之间的关系是线性和模块化的。parse_arguments函数独立运行,用于解析命令行参数并获取练习文件和答案文件的路径。read_files函数根据这些路径读取相应的文件内容。parse_fraction函数被用来将字符串形式的分数解析成Fraction对象,以便进行精确的数学运算。calculate_expression函数接受操作数和运算符列表,计算表达式的结果。check_answers函数遍历练习和答案,利用parse_fraction和calculate_expression函数来验证每个答案的正确性,最后输出正确和错误的答案列表。整个流程由main函数控制,它按顺序调用上述函数来完成整个检查过程。

4.代码说明

功能一:

关键代码流程图:

代码如下

# 生成算术表达式
def generate_expression(range_limit, num_operators):
    """Generate an arithmetic expression."""
    operands = [generate_number(range_limit) for _ in range(num_operators + 1)]
    operators = [generate_operator(allow_subtract=True, allow_divide=True) for _ in range(num_operators)]

    # 确保结果非负
    while True:
        result = calculate_expression(operands, operators)
        if result >= 0:
            break
        operands = [generate_number(range_limit) for _ in range(num_operators + 1)]
        operators = [generate_operator(allow_subtract=True, allow_divide=True) for _ in range(num_operators)]

    # 创建表达式字符串,并在需要的地方添加括号
    expression = f"{format_number(operands[0])} "
    for op_symbol, operand in zip(operators, operands[1:]):
        if op_symbol in ['-', '/']:
            expression += f" {op_symbol} ({format_number(operand)})"
        else:
            expression += f" {op_symbol} {format_number(operand)}"
    return expression, format_number(result)

generate_expression函数通过随机生成操作数和运算符来构建算术表达式,并确保结果非负。如果表达式计算结果为负,它会重新生成操作数和运算符,直到结果满足要求。最后,函数返回格式化后的表达式和结果。

功能2:

关键代码流程图如下:

代码如下

def write_grades(correct, wrong, grade_file):
    """
    Write the grades to a file.
    """
    with open(grade_file, 'w', encoding='utf-8') as f_grade:
        f_grade.write(f"Correct: {len(correct)} ({', '.join(map(str, correct))})\n")
        f_grade.write(f"Wrong: {len(wrong)} ({', '.join(map(str, wrong))})\n")

write_grades函数的思路是将正确和错误的答案列表及其数量写入指定的文件中。它首先打开一个文件用于写入,然后分别计算正确答案和错误答案的数量,并将它们与答案本身一起格式化为字符串,最后将这些信息写入文件的相应行中。这个过程确保了成绩的记录既清晰又易于理解。

5.代码质量分析

功能1代码质量分析

功能2代码质量分析

功能1性能分析代码质量分析

功能2性能分析代码质量分析

功能1测试代码质量分析

功能2测试代码质量分析

功能1代码测试覆盖率

功能2代码测试覆盖率

6.测试运行

测试用例1


预期结果:
Correct:3(4,5,7)
Wrong:7(1,2,3,6,8,9,10)
实际结果:

测试用例2


预期结果:
Correct:3(1,2,3)
Wrong:2(2,3)
实际结果:

测试用例3


预期结果:
Correct:3(1,2,5,6)
Wrong:2(3,4)
实际结果:

测试用例4


预期结果:
Correct:5(1,2,5,6,7)
Wrong:2(3,4)
实际结果:

测试用例5


预期结果:
Correct:8(1,2,3,4,6,7,8,10)
Wrong:3(5, 9, 11)
实际结果:

测试用例6


预期结果:
Correct:4(1,2,5,6)
Wrong:2(3,4)
实际结果:

测试用例7


预期结果:
Correct:2(1,3)
Wrong:1(2)
实际结果:

测试用例8


预期结果:
Correct:2(1,3)
Wrong:1(2)
实际结果:

测试用例9


预期结果:
Correct:3(1,3,4)
Wrong:1(3)
实际结果:

测试用例10


预期结果:
Correct:3(1,2,3,4,7)
Wrong:2(5,6)
实际结果:

通过十个测试用例,实际结果与我们预期的结果一致,所以可以说明我们的程序是正确的。

7.项目小结

在这次结对编程项目中,我们共同撰写了一个博客,不仅锻炼了我们的编程技能,还增强了我们的团队协作能力。以下是我们对这次合作的小结:
项目成败得失:
在做项目过程中,我们定期进行沟通,确保双方对项目的目标和进度有清晰的认识。并根据各自的强项进行了合理的分工,这提高工作效率。同时,我们发现在项目初期对时间的估计过于乐观,导致后期需要加班赶工。
分享经验:
我们应该更早地开始项目,并为不可预见的问题留出更多缓冲时间。
结对感受:
结对编程是一种非常有益的体验。它不仅让我们有机会从对方那里学习,还让我们意识到团队合作的力量。在编码时,有另一双眼睛可以发现错误和潜在的改进点,这大大提高了我们的代码质量。
对彼此的评价:
成员1: 成员2的耐心和对细节的关注给我留下了深刻的印象,代码审查非常细致,帮助我改进了我的编码习惯。
成员2: 成员1的创新思维和快速解决问题的能力对我很有启发,技术洞察力帮助我们克服了一些技术难题。
总的来说,这次结对编程经历对我们两人都是一次宝贵的学习机会,我们期待将来有更多的机会继续合作。

posted @ 2024-09-27 17:37  再睡亿分钟  阅读(58)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3