首页 > 编程语言 >结对项目——实现一个自动生成小学四则运算题目的命令行程序

结对项目——实现一个自动生成小学四则运算题目的命令行程序

时间:2024-09-23 13:01:06浏览次数:8  
标签:结对 题目 命令行 四则运算 生成 答案 answer txt

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/
这个作业要求在哪里 结对项目 - 作业 - 计科22级34班 - 班级博客 - 博客园 (cnblogs.com)
这个作业的目标 结对项目——实现一个自动生成小学四则运算题目的命令行程序
成员1 陈奕奕 3222004552
成员2 林闰埼 3222004595

Only-a-nose/PairWork (github.com)

1. PSP2.1表格

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

2.性能分析

使用 cProfile 进行性能分析

cProfile 是 Python 内置的性能分析器,能够记录函数的调用次数和执行时间,帮助发现性能瓶颈。

  • 使用 cProfile 分析整个程序

在命令行运行程序时,使用 cProfile 来分析程序的性能,命令如下:

python -m cProfile -s time D:\pythonProject1\Software_Engineer\MyApp.py -n 10 -r 10
  • -s time:按执行时间对结果进行排序,找到执行时间最长的函数。

  • MyApp.py 后跟的参数依然是程序的命令行参数,比如 -n 是生成题目个数,-r 是数值范围。

  • 分析结果

cProfile 的输出将显示每个函数的以下内容:

  • ncalls:调用的次数。
  • tottime:该函数中不包括子函数的总执行时间。
  • percall:每次调用该函数的平均时间(tottime 除以 ncalls)。
  • cumtime:该函数及其子函数的累计执行时间。
  • percall (cumtime):每次调用该函数的累计时间(cumtime 除以 ncalls)。

  • 将性能分析结果保存为文件

可以将 cProfile 的结果输出到文件进行进一步分析:

python -m cProfile -o output.pstats D:\pythonProject1\Software_Engineer\MyApp.py -n 10 -r 10
  • 使用 pstats 模块对文件中的数据进行查看和排序
import pstats
p = pstats.Stats('C:\\Users\\陈奕奕\\output.pstats')
p.strip_dirs().sort_stats('time').print_stats(10)  # 打印执行时间最长的前10个函数

3.设计实现过程

1. 程序概述

本程序旨在生成小学四则运算题目,并且支持对用户的答案文件进行批改。程序通过命令行参数控制生成题目的数量、数值范围,以及判定答案的功能。生成的题目和答案分别存储在 Exercises.txtAnswers.txt 文件中,判定结果保存在 Grade.txt 文件中。

2. 代码组织结构

程序主要由四个功能模块组成:

  1. 生成题目:生成符合条件的四则运算表达式。
  2. 计算答案:计算生成题目的答案。
  3. 判定对错:根据用户提供的答案文件与程序计算的答案进行比较,输出批改结果。
  4. 命令行参数解析:解析用户通过命令行输入的参数,调用不同的功能。

3. 关键函数设计

  1. generate_question(range_value, operator_count=3)

    • 功能:根据给定数值范围 range_value 生成四则运算题目。
    • 输入:数值范围 range_value 和运算符个数 operator_count
    • 输出:返回一个运算表达式,包含自然数或真分数,以及最多 3 个运算符。
    • 逻辑:
      1. 随机生成自然数或真分数作为操作数。
      2. 随机选择运算符。
      3. 拼接操作数和运算符,生成一个完整的四则运算表达式。
  2. calculate_answer(expression)

    • 功能:根据生成的表达式计算答案。
    • 输入:四则运算表达式 expression
    • 输出:返回计算结果的真分数格式,或者在除零时返回 "undefined"。
    • 逻辑:
      1. 使用 Python 的 eval() 计算表达式。
      2. 捕捉除零异常,并输出 "undefined"。
  3. check_answers(exercise_file, answer_file)

    • 功能:检查用户提供的答案文件,判定每道题目对错。
    • 输入:题目文件路径 exercise_file 和答案文件路径 answer_file
    • 输出:生成一个包含判定结果的 Grade.txt 文件。
    • 逻辑:
      1. 读取题目和答案文件,按行处理。
      2. 逐行比较程序计算的答案和用户提供的答案,统计正确与错误的题目。
      3. 将结果写入 Grade.txt
  4. generate_exercises_and_answers(n, range_value)

    • 功能:生成 n 道题目并计算答案,存入 Exercises.txtAnswers.txt 文件。
    • 输入:题目个数 n 和数值范围 range_value
    • 输出:生成的题目和答案分别存入两个文件中。
  5. main()

    • 功能:命令行解析,控制程序的整体逻辑。
    • 逻辑:
      1. 如果传入 -n-r 参数,生成指定数量的题目和答案。
      2. 如果传入 -e-a 参数,进行答案对错判定。
      3. 如果参数不全,打印帮助信息。

4. 模块之间的关系

  • 生成题目模块generate_question())会调用生成随机数和运算符,最终返回一个四则运算表达式。
  • 计算答案模块calculate_answer())会对生成的四则运算表达式进行计算,并将结果以真分数的形式返回。
  • 判定对错模块check_answers())读取生成的题目和用户提供的答案进行比较,统计对错并输出到文件。
  • 命令行解析模块main())控制程序的主流程,解析参数决定调用生成题目或判定答案的功能。

5. 关键流程图

1. generate_question() 函数流程图

2. calculate_answer() 函数流程图

3. check_answers() 函数流程图

6. 总结与改进

  • 该程序的设计简洁,使用了模块化设计,方便各个功能的扩展。
  • 使用命令行参数控制生成题目和判定答案功能,使得程序灵活性较强。
  • 在未来的改进中,可以增加更多的输入校验功能,如防止用户输入无效参数,或者确保用户提供的答案文件格式正确。

4.代码说明

1. 模块导入

import argparse
import random
from fractions import Fraction
  • argparse:用于处理命令行参数。
  • random:用于生成随机数,帮助创建随机四则运算题目。
  • fractions.Fraction:用于处理真分数,使得生成题目时可以包含分数运算。

2. 生成四则运算题目的函数:generate_question()

def generate_question(range_value, operator_count=3):
    operators = ['+', '-', '*', '/']
    numbers = []
    for _ in range(operator_count + 1):
        if random.choice([True, False]):
            numerator = random.randint(1, range_value - 1)
            denominator = random.randint(2, range_value)
            fraction = Fraction(numerator, denominator)
            numbers.append(fraction)
        else:
            numbers.append(random.randint(1, range_value - 1))

    expression = str(numbers[0])
    for i in range(operator_count):
        op = random.choice(operators)
        expression += f" {op} {numbers[i + 1]}"
    
    return expression
  • 功能:随机生成包含真分数和自然数的四则运算题目。
  • 参数
    • range_value:控制生成的随机数的范围。
    • operator_count:控制运算符的数量,默认是3个运算符。
  • 流程
    1. 随机选择数字,可以是自然数或真分数。
    2. 在数字之间插入随机运算符(+, -, *, /)。
    3. 返回完整的四则运算表达式字符串。

3. 计算表达式结果的函数:calculate_answer()

def calculate_answer(expression):
    try:
        answer = eval(expression)
        return str(Fraction(answer).limit_denominator())
    except ZeroDivisionError:
        return "undefined"
    except Exception as e:
        return f"Error: {e}"
  • 功能:计算四则运算题目的正确答案。
  • 参数expression 是待计算的数学表达式字符串。
  • 流程
    1. 使用 Python 的内置 eval() 函数计算表达式的值。
    2. 将计算结果转换为最简分数形式。
    3. 如果遇到除以零错误,返回 "undefined"
    4. 处理其他异常并返回错误信息。

4. 判定答案对错的函数:check_answers()

def check_answers(exercise_file, answer_file):
    with open(exercise_file, "r") as ef, open(answer_file, "r") as af, open("Grade.txt", "w") as grade_file:
        correct = []
        wrong = []
        exercises = ef.readlines()
        answers = af.readlines()

        for i in range(len(exercises)):
            exercise = exercises[i].split('=')[0].split('. ')[1].strip()
            expected_answer = calculate_answer(exercise)
            given_answer = answers[i].split(". ")[1].strip()

            if expected_answer == given_answer:
                correct.append(i + 1)
            else:
                wrong.append(i + 1)

        grade_file.write(f"Correct: {len(correct)} ({', '.join(map(str, correct))})\n")
        grade_file.write(f"Wrong: {len(wrong)} ({', '.join(map(str, wrong))})\n")
  • 功能:检查学生的答案是否正确,并将结果写入 Grade.txt 文件。
  • 参数
    • exercise_file:题目文件的路径。
    • answer_file:答案文件的路径。
  • 流程
    1. 从题目文件和答案文件中读取数据。
    2. 对每个题目,提取出数学表达式并计算正确答案。
    3. 比较计算的答案和给出的答案。
    4. 记录正确和错误的题目编号,并将结果写入 Grade.txt 文件。

5. 生成题目和答案的函数:generate_exercises_and_answers()

def generate_exercises_and_answers(n, range_value):
    with open("Exercises.txt", "w") as exercise_file, open("Answers.txt", "w") as answer_file:
        for i in range(1, n + 1):
            question = generate_question(range_value)
            answer = calculate_answer(question)
            exercise_file.write(f"{i}. {question} =\n")
            answer_file.write(f"{i}. {answer}\n")
  • 功能:生成题目和对应的答案,分别写入 Exercises.txtAnswers.txt 文件中。
  • 参数
    • n:题目的数量。
    • range_value:控制生成的随机数的范围。
  • 流程
    1. 生成指定数量的四则运算题目。
    2. 计算每道题目的正确答案。
    3. 将题目和答案分别写入两个文件中。

6. 主函数:main()

def main():
    parser = argparse.ArgumentParser(description="四则运算生成器")
    parser.add_argument("-n", type=int, help="生成题目的个数")
    parser.add_argument("-r", type=int, help="题目中数值的范围")
    parser.add_argument("-e", type=str, help="题目文件路径")
    parser.add_argument("-a", type=str, help="答案文件路径")

    args = parser.parse_args()

    if args.n is not None and args.r is not None:
        generate_exercises_and_answers(args.n, args.r)
        print(f"生成了 {args.n} 道题目,数值范围为 0 到 {args.r}")
    elif args.e and args.a:
        check_answers(args.e, args.a)
        print(f"判定答案对错,结果已存入 Grade.txt 文件。")
    else:
        parser.print_help()
  • 功能:处理命令行参数,调用相应的功能。
  • 参数说明
    • -n:生成题目的数量。
    • -r:控制生成题目的数值范围。
    • -e-a:分别指定题目文件和答案文件的路径,用于判定答案对错。
  • 流程
    1. 如果提供了 -n-r 参数,生成题目和答案文件。
    2. 如果提供了 -e-a 参数,检查给出的答案是否正确。
    3. 如果参数不完整,显示帮助信息。

7. 程序入口

if __name__ == "__main__":
    main()
  • 功能:这是标准的 Python 程序入口,确保当文件作为脚本运行时调用 main() 函数。

5.测试运行

  1. 生成10道题目,数值范围在10以内

    python MyApp.py -n 10 -r 10
    
  2. 检查题目和答案文件的对错

    python MyApp.py -e Exercises.txt -a Answers.txt
    
  3. 命令窗口:


  1. 运行结果:

    • Exercises.txt

  • Answers.txt

  • Grade.txt

6.项目小结

1. 项目背景与目标

在这个结对项目中,我们的目标是开发一个四则运算题目生成器,并实现一个自动化的答案判定系统。该系统需要支持生成随机的四则运算题目(包括自然数和真分数),计算这些题目的正确答案,并对给出的答案进行准确的判定。项目的关键任务包括编写代码来生成题目、计算答案、检查答案的正确性,以及处理命令行参数以实现这些功能。

2. 成功经验

1. 任务分配与协作

我们在项目初期对任务进行了合理的分配。一方负责设计和实现题目生成和答案计算的核心逻辑,另一方则专注于答案的判定和命令行接口的实现。这种分工有效提高了工作效率,使得每个人可以专注于自己擅长的领域。

2. 测试与调试

我们制定了详尽的测试计划,包括单元测试和集成测试。通过 PyCharm 和命令行进行性能分析和测试,及时发现了潜在的问题并进行了修复。这种方法确保了代码的稳定性和准确性。

3. 文档与说明

我们在代码中添加了详细的注释和文档说明,解释了每个函数的功能和参数。这不仅帮助我们自己在后续维护时更容易理解代码,也使得项目对其他开发者更友好。

3. 遇到的挑战与教训

1. 异常处理

在处理四则运算题目的计算时,我们遇到了除以零的错误。最初没有考虑到这一点,导致了程序崩溃。经过调整,我们加入了专门的异常处理机制,以确保程序在遇到除以零的情况时能够返回 "undefined",而不是崩溃。

2. 参数处理

最开始对命令行参数的处理不够完善,导致在不同环境下运行时出现了参数解析错误。通过调试和修正,我们改善了参数处理的代码,确保了命令行工具的稳定性和可靠性。

3. 文件路径问题

在读取文件路径时,遇到了 Unicode 编码问题。通过使用原始字符串(r'path')来处理路径,我们解决了这个问题,并确保代码在不同操作系统上能够正常运行。

4. 结对感受

合作中的闪光点
  • 高效的沟通:我们在项目中保持了频繁而有效的沟通。每当遇到问题时,我们都能够迅速协作找到解决方案。这种高效的沟通大大提高了项目的推进速度。
  • 互补的技能:我们两个人在技能上互补,一方擅长逻辑和算法设计,另一方则精通命令行工具和文件操作。这种互补让我们的项目在各方面都能达到较高的质量。
建议
  • 定期代码审查:虽然我们在项目中保持了良好的沟通,但定期的代码审查可以帮助更早地发现潜在问题。建议在未来的项目中加入更多的代码审查环节。
  • 增强文档编写:虽然项目中有详细的注释和文档,但在复杂的功能实现中,提供更多的技术文档和使用指南会更有助于项目的维护和扩展。

5. 总结

通过这次结对项目,我们不仅完成了四则运算题目生成器和答案判定系统的开发任务,还在实践中积累了宝贵的经验。项目中的挑战和问题让我们认识到在开发过程中异常处理和参数管理的重要性,同时也让我们意识到团队合作和技能互补的优势。未来,我们将继续优化我们的工作方法,以确保项目的高效和稳定运行。


博文撰写者: 陈奕奕 和 林闰埼

标签:结对,题目,命令行,四则运算,生成,答案,answer,txt
From: https://www.cnblogs.com/Onlyanose/p/18426880

相关文章

  • 结对项目
    这个作业属于哪个课程 计科22级12班这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-12/homework/13221这个作业的目标 完成结对项目,合作实现自动生成小学四则运算题目的功能,了解软件开发流程姓名 学号 github地址刘家辉 3122004443 Rawven一.PSP表格PSP......
  • 结对项目
    目录结对项目1.PSP2.1表格2.性能分析3.设计实现过程1.结构1.number2.函数1.solve()2.create()3.getstring()4.pplus(strings)5.check(strings)6.read(strings)7.work(vectorpro)8.write1(vectorans)9.compare(vectorans,vectorans1)10.write2(vectorright,vectorwron......
  • linux命令行读写uboot环境变量
    1. fw_printenv& fw_setenvbuild,see: u-boot-2020.04/tools/env/READMEcd u-boot-2020.04makeCROSS_COMPILE=arm-linux-envtoolsYoushouldthencreateasymlinkfromfw_setenvtofw_printenv.2.test2.1read2.2write会自动保存到emmc/flash中3......
  • 结对项目:四则运算题目生成
    这个作业属于哪个课程22级计科1班这个作业要求在哪里作业要求这个作业的目标自动生成小学四则运算题目github项目链接链接姓名&学号姓名学号万凯毅3122004788周彦安3122004804PSPPSP2.1PersonalSoftwareProcessStages预估耗时(......
  • Acronis True Image 完整版的一些常用命令行参数:
    AcronisTrueImage完整版的一些常用命令行参数:常用命令参数备份:bashCopyCodeAcronisTrueImage.exe/backup/source:"源路径"/destination:"目标路径"/name:"备份名称"恢复:bashCopyCodeAcronisTrueImage.exe/restore/source:"备份文件路径"/destinatio......
  • 结对项目
    这个作业属于哪个课程计科22级12班这个作业要求在哪里作业要求这个作业的目标完成结对项目,合作实现自动生成小学四则运算题目的功能,了解软件开发流程 姓名学号github地址雷志毅3122004394lzy394李耿豪3122004395SE-test一.PSP表格P......
  • Go:开源命令行词典工具 - `dictcli` 推荐
    在日常的语言学习或工作中,我们经常需要快速查询单词的定义、同义词等信息。为了满足这种需求,开源社区中涌现了很多便捷的工具。今天,我非常高兴向大家推荐一个出色的开源项目——dictcli,它是一个用Go语言编写的命令行词典查询工具,支持本地查询单词定义,并且将词典数据嵌入到......
  • 命令行提示:-bash-4.2$ ,原因分析及解决
    inux普通用户登录后,命令行提示:-bash-4.1$,原因分析及解决有时候在使用用户登陆Linux系统时会发现,命令行提示符成了:-bash-4.2$,不显示用户名,路径信息。 原因:用户家目录里面与环境变量有关的文件被删除所导致的也就是这俩文件:.bash_profile.bashrc这两个文件被删除了,导致......
  • PHP命令行脚本接收参数
    使用$argvor$argc参数接收<?phpecho"接收到{$argc}个参数";print_r($argv);phptest.php接收到1个参数Array(   [0]=>test.php)phptest.phpabcd接收到5个参数Array(   [0]=>test.php   [1]=>a   [2]=>b   [3]=>c......
  • 《华为三台交换机堆叠的详细命令行配置示例》
    华为三台交换机堆叠的详细命令行配置示例目录目录华为三台交换机堆叠的详细命令行配置示例 在Switch1(作为主交换机)上的配置: 1. 进入系统视图2. 开启堆叠功能并设置堆叠域编号(假设为10)3. 设置堆叠优先级(假设为200,数值越大越优先成为主交换机)4. 配置堆叠端口 ......