0. 课程概要
这个作业属于哪个课程 | |
---|---|
组队成员信息
练东晖 | |
汤陶然 |
1. PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
·Estimate | ·估计这个任务需要多少时间 | ||
Development | 开发 | ||
·Analysis | ·需求分析(包括学习新技术) | ||
·DesignSpec | ·生成设计文档 | ||
·DesignReview | ·设计复审 | ||
·CodingStandard | ·代码规范(为目前的开发制定合适的规范) | ||
·Design | ·具体设计 | ||
·Coding | ·具体编码 | ||
·CodeReview | ·代码复审 | ||
·Test | ·测试(自我测试,修改代码,提交修改) | ||
Reporting | 报告 | ||
·TestReport | ·测试报告 | ||
·SizeMeasurement | ·计算工作量 | ||
·Postmortem&ProcessImprovementPlan | ·事后总结,并提出过程改进计划 |
2. 接口设计及实现过程
模块设计与组织
总共分为【生成题目】、【计算答案】、【写入文件】和【对比作答】四个模块
1. 生成题目模块
- 功能概述:
这个模块负责生成四则运算题目。 - 关键函数:
main()
:主函数
__init__
:初始化SimHash对象,接受文本和哈希位数作为参数。
gen_random()
:根据随机数生成规则,生成整数和真分数。
gen_op()
: 随机选择运算符。(➕ ➖ ✖ ➗)
gen_equation()
: 生成随机的表达式。
check_validity(equation)
: 检查表达式是否合法。
· equation:表达式
generate_questionnaire(n, generated_equations, max_attempts)
: 生成题目并检查题目是否重复
· n:需要生成的题目数量。
· generated_equations:已生成的算式集合,用于检查算式是否已存在。
· max_attempts(可选):最大尝试次数,默认为10000,避免无限循环。
sorted_equation(equation)
: 将算式的各个元素排序,便于比较。
· equation:表达式
2. 计算答案模块
- 功能概述:
这个模块主要负责计算四则运算表达式的结果 - 关键函数:
calc(equation)
: 计算一个四则运算式的结果。
· equation:表达式
3. 写入文件模块
- 功能概述:
这个模块负责将题目和答案写入对应的文件中 - 关键函数:
main()
: 主函数,控制整个流程,包括调用write_to_file()
将题目和答案写入文件。
write_to_file(filename, content)
: 将 content 写入指定的文件 filename。
· filename:文件的主名字(比如Answers.txt的主名字为Answers)
· content:包括题目和答案
convert_to_mixed_number(numerator, denominator)
: 将计算结果中的假分数转化为真分数。
· numerator:计算结果的分子
· denominator:计算结果的分母
4. 对比作答模块
- 功能概述:
这个模块负责比较标准答案和用户的答案,并生成评分文件。 - 关键函数:
compare_answers(keyFile, answerFile)
: 比较标准答案与所作答的答案,返回正确和错误的题目编号。
· keyFile:标准答案文件的主名字(比如Answers.txt的主名字为Answers)
· answerFile:上传答案的主名字(比如daan.txt的主名字为daan)
write_grade(correct_indices, wrong_indices)
: 将正确与错误的题数和题号以及正确率写入Grade.txt文件
· correct_indices:作答正确的题目索引
· wrong_indices:作答错误的题目索引
关键算法说明
1. 检查表达式是否合法:首先,我们通过 replace() 方法将所有括号和多余的符号移除,使得表达式更清晰简洁。接着,我们通过检查表达式中是否包含 '÷ 0' 来确保没有除以零的情况发生。然后,通过递归进行“-”号前后的比较,确保减法运算不会产生负数。
2. 检查题目是否重复:
generate_questionnaire(n, generated_equations, max_attempts)
该函数的核心思想是通过循环生成题目,每生成一个就检查在已有题目中是否有答案一样的题目,若有,则对新生成题目和符合条件题目分别进行元素拆分并排序,然后比较,若相同则重新生成新题目,若不同或者无答案一样题目,则直接添加到题目列表中。
sorted_equation(equation)
该函数的核心思想是使用正则表达式 re.findall() 提取表达式中的数字和运算符并对提取的元素进行升序排序。
3. 对作答答案生成评分文件:
该函数的核心思想是打开标准答案文件和完成答案文件,逐行比较它们的内容。将正确的题目的索引放入 correct_indices 列表中,将错误的题目的索引放入 wrong_indices 列表中。
代码组织
- 代码按模块划分,每个模块负责一个特定的功能,使得代码清晰易读。
- 使用了类的概念,将各个功能封装在类中,使得代码结构更加清晰,易于维护。
独到之处
-
算式合法性检查:程序在生成和计算算式时,通过check_validity函数对算式进行合法性检查,确保了生成的题目都是合法且有解的。
-
算式去重功能:程序通过generated_equations集合来确保生成的题目不会重复,在生成大量题目时,可以保证题目的多样性。
-
使用标准库 fractions:使用了 Python 标准库中的 fractions 模块来处理真分数的运算和转换,这使得代码更为简洁和可读。
-
用户交互界面:为程序添加了一个简单而美观的用户交互界面,使得用户可以直观地输入生成题目的参数,增加了程序的友好性和易用性。
-
错误处理:在程序中合理地使用了异常处理,对可能出现的错误情况进行了处理,保证了程序的稳定性。
3. 性能分析
4. 计算模块部分单元测试
1. 生成随机题目测试
(为方便需求9的验证,先以20题为例子)
在交互界面输入相应数据
生成的文件确有20个不重复且满足条件的题目,题目文件也有相应正确的答案
2. 生成评分文件测试
在相应目录下,创建一个答案文件,并输入答案,然后上传文件名字
对比答案与标答,生成评分文件
(分别在整数、真分数的系数部分和分数部分(分子分母各一)进行修改,确保每一种对比都能判错)
2. 生成大量题目测试(10000)
结果如下:
5. 计算模块部分异常处理说明
核心思想
首先,它接受一个表达式 equation 作为输入。
其次,它试图计算这个表达式的值。
如果计算成功且结果是非负数,则将结果返回。
如果计算遇到异常(如除零错误 ZeroDivisionError、断言错误 AssertionError 或语法错误 SyntaxError),则程序会重新生成一个新的表达式并再次尝试计算,这是一个递归调用。
详细解释
equation = equation.replace("'", "+")
:这一步将真分数的加法形式转化为标准的加法表达式,方便后续计算。
value = eval(equation.translate(punctuation_table))
:这一行将经过处理的表达式传递给 Python 的 eval 函数,它会执行字符串中的有效 Python 表达式。在这里,它会计算表达式的值。
assert value >= 0
:这一行是一个断言,用于确保计算结果是非负数。如果结果小于零,会触发 AssertionError 异常。
except (ZeroDivisionError, AssertionError, SyntaxError)
:这是异常处理部分。如果出现了除零错误、断言错误或语法错误,程序将执行以下操作。
return calc(gen_equation())
:如果出现了上述异常,程序会重新生成一个新的表达式(通过调用 gen_equation()),然后递归调用 calc 函数来尝试计算新的表达式。
独到之处
这个模块的独到之处在于,它不仅仅是一个简单的计算函数,还包含了对异常情况的处理和递归调用,确保了程序生成的表达式都是合法且有解的。如果出现了不符合要求的情况,它会重新生成新的表达式并尝试计算,这增加了程序的健壮性和稳定性。
6. 总结与分工
- 项目分工:
- 练东晖:负责实现四则运算的整体代码编写及修改,博客的撰写
- 汤陶然:负责数据检测,与文件的测试
- 项目总结:
- 这个项目通过组织合理的代码结构和合适的函数设计,实现了一个功能完备、稳健可靠的四则运算题目生成器。同时,项目中涵盖了大量异常处理和边界条件的考虑,保证了程序的健壮性。通过用户交互界面,使得程序的使用更为方便。
- 明确分工:每个人在团队中都要明确自己的角色和任务,避免任务交叉和资源浪费。
积极互动:积极参与讨论和交流,分享自己的想法和看法,以促进项目的良性发展。
尊重和信任:相互尊重和信任是合作的基石。在合作中,团队成员需要相互支持,共同努力实现项目目标。
持续学习:合作的过程中,会接触到各种各样的技术和工具,团队成员可以通过学习和实践不断提升自己的技能。