四则运算题目的生成
四则运算题目的生成
github地址:https://github.com/gomevie/gomevie/tree/master
这个作业属于哪个课程 | 广工计院计科34班软工 |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 生成数学四则运算的练习题和答案 |
作业成员 | 陈国威 3122004559 |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 600 | 650 |
Development | 开发 | 40 | 60 |
· Analysis | · 需求分析(包括学习新技术) | 60 | 50 |
· Design Spec | · 生成设计文档 | 30 | 25 |
· Design Review | · 设计复审 | 30 | 30 |
· Coding Standard | · 代码规范(为目前的开发制定合适的规范) | 20 | 20 |
· Design | · 具体设计 | 50 | 45 |
· Coding | · 具体编码 | 120 | 120 |
· Code Review | · 代码复审 | 25 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 45 |
Reporting | 报告 | 60 | 90 |
· Test Report | · 测试报告 | 20 | 25 |
· Size Measurement | · 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结,并提出过程改进计划 | 20 | 30 |
合计 | 615 | 650 |
代码简解
导入模块:
random:用于生成随机数。
sympy:用于数学表达式的解析和计算。
argparse:用于处理命令行参数。
全局变量:
operate:一个字典,用于将运算符映射到它们的字符串表示。
函数定义:
save_data:将表达式和结果保存到两个文件中。
calculate_expression:计算数学表达式并返回结果的分数形式。
is_true_fraction:检查表达式是否为真分数。
is_valid_expression:检查表达式是否有效。
generate_true_fraction:生成一个真分数。
generate_expressions:生成指定数量的四则运算表达式。
main:主函数,生成表达式并保存到文件。
read_answers:从文件中读取答案。
compare_answers:比较正确答案和学生答案。
write_grades_to_file:将成绩统计结果写入文件。
calculate_grades:计算并记录学生答案的正确率。
命令行参数处理:
使用argparse库来定义和解析命令行参数。
参数包括题目数量、运算最大值、学生答案文件名、正确答案文件名和输出文件名。
主程序:
如果没有提供学生和正确答案文件,将生成新的表达式和答案。
如果提供了学生和正确答案文件,将比较答案并生成成绩统计。
错误处理:
在多个地方使用了异常处理来捕获错误,并在发生错误时返回错误信息。
下面是项目的流程图:
函数精解
generate_expressions(max_value, count)
功能
生成指定数量的四则运算表达式。
实现细节
1.使用random.sample随机选择1到3个运算符。
2.循环遍历运算符,生成两个随机真分数,并构建表达式。
3.随机添加括号,以增加表达式的复杂性。
calculate_expression(expression)
功能
计算给定的数学表达式,并将其结果转换为分数形式。
实现细节
1.使用sympify函数解析和计算表达式。
2.如果结果是整数,直接转换为整数。
3.如果结果不是整数,转换为分数形式,并限制分母的大小。
save_data(data, filename_expressions, filename_results)
功能
将生成的表达式及其计算结果保存到文件中。
实现细节
1.使用with open打开两个文件,一个用于保存表达式,另一个用于保存结果。
2.遍历数据,将表达式和结果写入对应的文件。
read_answers(filename)
功能
从文件中读取答案。
实现细节
1.使用with open打开文件。
2.读取每一行,并去除空白字符。
compare_answers(correct, student)
功能
比较正确答案和学生的答案。
实现细节
1.遍历正确答案和学生答案,比较它们是否相同。
2.计算正确和错误的答案数量。
write_grades_to_file(correct_count, wrong_count, correct_list, wrong_list, output_file)
功能
将成绩统计结果写入文件。
实现细节
1.使用with open打开文件。
2.将正确和错误的答案数量以及对应的题目编号写入文件。
calculate_grades(correct_answers_file, student_answers_file, output_file)
功能
整合读取答案、比较答案和写入成绩的流程。
实现细节
1.调用read_answers读取正确答案和学生答案。
2.调用compare_answers比较答案。
3.调用write_grades_to_file将结果写入文件。
main(max_value, count)
功能
程序的主函数,生成表达式并保存结果。
实现细节
1.检查输入参数的有效性。
2.调用generate_expressions生成表达式。
3.调用save_data保存结果。
代码的主要功能是生成数学表达式和答案,然后比较学生的答案和标准答案。关键函数包括生成表达式、计算表达式、保存数据、读取数据、比较答案和写入成绩。
性能分析
性能分析的目的在于识别程序中的性能瓶颈,以便进行必要的优化。为此,利用了Python的cProfile模块来收集程序运行时的性能数据,如图:
主要性能瓶颈
分析结果显示,generate_expressions函数是程序中运行时间最长的部分,平均耗时0.353秒。该函数负责生成数学表达式,其性能对整个程序的响应速度有直接影响。
此外,main函数也显示出较高的耗时,平均耗时0.354秒。由于main函数是程序的入口点,并且调用了generate_expressions,因此其性能同样关键。
is_valid_expression和is_true_fraction函数虽然单独的运行时间不长,但它们在程序中被频繁调用,累计耗时分别为0.153秒和0.0961秒,表明这些函数的总体影响可能比单个调用的耗时要大。
calculate_expression函数的运行时间为0.0965秒,考虑到其在表达式计算中的核心作用,这一部分的性能同样值得关注。
Sympy库中的sympify和parse_expr函数也显示出了较高的耗时,分别为0.319秒和0.308秒。这些函数用于解析和处理数学表达式,它们的性能直接影响到程序的计算效率。
性能数据分析
从性能数据中可以看出,程序的性能在很大程度上受到数学表达式生成和解析函数的影响。这些函数的运行时间占据了程序总运行时间的大部分。
结论
性能分析揭示了Myapp.py的性能特点和潜在瓶颈。虽然当前的分析并未涉及具体的优化措施,但它为未来的性能改进提供了重要的数据支持和方向指导。通过识别出关键函数的性能表现,可以更有针对性地进行后续的优化工作。
单元测试
概述
单元测试是软件开发过程中的关键环节,旨在验证程序的各个独立组件是否按预期工作。本次测试针对的是“四则运算”项目中的表达式计算功能,测试脚本位于test_and_analysis目录下。
测试范围
测试覆盖了以下几种情况:
正常表达式,结果为整数:
测试用例验证了程序能够正确计算整数结果的表达式。
正常表达式,结果为分数:
测试用例验证了程序能够正确计算分数结果的表达式。
正常表达式,结果为带分数:
测试用例验证了程序能够正确处理和计算带分数的表达式。
含错误的表达式:
测试用例验证了程序能够识别并提示错误信息的无效表达式。
测试方法
测试使用了Python的unittest框架,通过断言(assert)来验证每个测试用例的预期结果。测试脚本包括:
test_calculate_expression():测试计算表达式的功能。
测试结果
测试结果显示,所有测试用例均通过,没有发现错误或异常行为。
测试代码
def test_calculate_expression():
# 正常表达式,结果为整数
assert calculate_expression("2+2") == "4"
assert calculate_expression("299+201") == "500"
# 正常表达式,结果为分数
assert calculate_expression("1/2 + 1/3") == "5/6"
assert calculate_expression("1/18 + 2/9") == "5/18"
# 正常表达式,结果为带分数
assert calculate_expression("3+2/3") == "3'2/3"
assert calculate_expression("1/2+2/3") == "1'1/6"
# 含错误的表达式
assert calculate_expression("a+b").startswith("Error:")
assert calculate_expression("2 + /3").startswith("Error:")
`
分析
测试结果表明,程序能够正确处理各种类型的数学表达式,并在遇到无效输入时给出适当的错误提示。这表明计算表达式的函数具有良好的健壮性和准确性。
结论
单元测试为程序的可靠性提供了有力的证据。所有测试用例的成功执行表明,当前版本的计算表达式功能符合预期,可以进行后续的集成和系统测试。
终端测试
概述
错误处理是确保软件健壮性的重要部分。通过测试程序对错误输入和异常情况的处理,可以验证程序的稳定性和用户友好性。
测试范围
本次测试专注于验证程序对以下错误情况的处理:
非法的命令行参数:
测试程序对负数题目数量和未提供的运算最大值的处理。
文件不存在:
测试程序在读取不存在的文件时的错误提示。
测试方法
测试通过直接在命令行中输入特定的参数来进行。测试脚本包括:
输入负数题目数量和未提供的运算最大值。
指定不存在的文件作为输入。
测试结果
测试结果显示,程序能够正确识别并处理错误情况,具体如下:
非法的命令行参数:
输入负数题目数量时,程序抛出ValueError,提示“参数必须是给定的自然数。”
未提供运算最大值时,程序同样抛出ValueError,提示“运算最大值必须是给定的自然数。”
文件不存在:
当尝试读取不存在的文件时,程序抛出FileNotFoundError,并明确指出文件不存在。
分析
测试结果表明,程序具备良好的错误识别和处理能力。对于非法的命令行参数和不存在的文件,程序能够给出清晰的错误提示,帮助用户了解问题所在。
结论
通过本次测试,验证了程序在遇到错误输入和异常情况时的稳定性和用户友好性。程序的错误处理机制能够有效地指导用户进行正确的操作,提高了程序的健壮性和可靠性。
总结
该项目成功实现了一个四则运算表达式生成与计算的应用程序。程序以其高效的算法和全面的错误处理机制为亮点,确保了在面对各种输入时都能稳定运行并给出准确的反馈。用户界面简洁直观,便于用户快速理解和操作。
程序在处理表达式生成和计算方面展现了出色的性能,同时能够优雅地处理异常情况,为用户提供了有用的错误信息,从而提升了整体的用户体验。此外,程序的文档齐全,增强了其可维护性和可扩展性。