一、
这个作业属于哪个课程 | 计科 |
---|---|
这个作业要求在哪里 | 结对项目 |
这个作业的目标 | 学习团队互助合作完成项目 |
二、团队成员
姓名 | 学号 |
---|---|
梁戬希 | 3121004914 |
刘润桦 | 3121004919 |
github链接:github
三、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 600 | 750 |
· Estimate | 估计这个任务需要多少时间 | 600 | 750 |
Development | 开发 | 520 | 800 |
· Analysis | 需求分析 (包括学习新技术) | 80 | 160 |
· Design Spec | 生成设计文档 | 40 | 40 |
· Design Review | 设计复审 | 60 | 40 |
· Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 20 |
· Design | 具体设计 | 60 | 60 |
· Coding | 具体编码 | 120 | 300 |
· Code Review | 代码复审 | 60 | 100 |
· Test | 测试(自我测试,修改代码,提交修改) | 70 | 80 |
Reporting | 报告 | 150 | 140 |
· Test Report | 测试报告 | 100 | 90 |
· Size Measurement | 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1270 | 1690 |
四、效能分析
函数调用结构图
性能分析图
可以看到,在改卷模式中,check()函数耗时最长;在出卷模式中,cal()函数耗时最长。综合来看,cal()函数无论在阅卷模式还是出卷模式都占用CPU极大的时间。
五、设计实现过程
1、main.py:这个文件包含了主要的程序入口,用于生成数学题目和保存答案,以及阅卷功能。它的主要功能如下:
main():程序的入口函数,根据命令行参数决定执行生成题目还是阅卷操作。
get_arguments():用于解析命令行参数,包括生成题目模式和阅卷模式的参数。
get_question(args):生成数学题目的核心函数,根据参数随机生成题目。
get_answer(question):根据生成的题目计算答案。
save_as_file(qst, save_path):将生成的题目或答案保存到文件中。
2、read_cal_check.py:这个文件包含了读取文件、阅卷操作和数学表达式计算的函数。它的主要功能如下:
readfile(qstpath):读取题目或答案文件,并将内容存储为列表。
check(q_list, a_list):进行阅卷操作,比较题目和答案是否正确,并返回正确和错误的题目索引。
cal(formula):计算数学表达式的值,包括处理带分数和分数的情况。
saveresult_as_file(res_list, savepath):将阅卷结果保存到文件中。
现在,让我们讨论代码的组织和关键函数:
3、main.py的组织和关键函数:
主程序入口是 main() 函数,它首先通过 get_arguments() 解析命令行参数,确定是生成题目还是阅卷操作。
如果是生成题目模式(operate.mode == 1),则调用 get_question() 生成题目,再调用 get_answer() 计算答案,最后使用 save_as_file() 保存题目和答案。
如果是阅卷模式(operate.mode == 2),则调用 readfile() 读取题目和答案文件,然后调用 check() 进行阅卷,最后使用 saveresult_as_file() 保存阅卷结果。
4、read_cal_check.py的组织和关键函数:
该文件主要负责读取文件、阅卷操作和数学表达式计算。
readfile(qstpath) 用于读取题目或答案文件,返回一个包含题目或答案的列表。
check(q_list, a_list) 用于进行阅卷操作,比较题目和答案的正确性,返回正确和错误的题目索引。
cal(formula) 是一个重要的数学表达式计算函数,它用于计算给定的数学表达式的值,包括处理带分数和分数的情况。它首先将算式中的字符 '×' 替换为 '*',字符 '÷' 替换为 '/',并去除多余的空格、等号和换行符。然后,它处理带分数和分数,并将它们替换为 fractions.Fraction 对象,以保留分数。最后,它通过 Python 的 eval() 函数计算表达式的值。
saveresult_as_file(res_list, savepath) 用于将阅卷结果保存到文件中,包括正确和错误的题目索引。
总体而言,这两个文件通过明确定义的函数,实现了清晰的代码组织,将不同功能的代码块模块化,使代码易于维护和扩展。关键函数是 get_question() 用于生成题目,cal(formula) 用于计算数学表达式,以及 check(q_list, a_list) 用于阅卷操作。这些函数提供了核心的功能,分别处理了题目生成、数学表达式计算和阅卷操作,使得整个程序的结构清晰可读。
六、代码说明
关键代码
整个程序的关键在于main主函数,主函数是整个程序的骨架。对于主函数来说,它的任务就是协同各个函数完成项目的指定功能,其思路大概为:
接收命令行参数并存储 -> 分支不同模式(出题模式和改卷模式)
出题模式:随机生成题目和答案 -> 保存题目和答案到文本中
改卷模式:读取题目文本和答案文本 -> 生成答案检验 -> 保存至检验文本
七、测试运行
10个测试用例
测试用例对应的答案
判定答案文件的对错
如果若干个答案出现错误
支持对10000道题目的生成
说明
在完成代码后,首先经过代码复查(自己和合作者分别复查),然后设置多个测试用例对程序测试、单元测试、回归测试等,最后再经过一次代码终审,可以确认自己的程序能够正确无误地运行。
八、项目小结
-
项目总结
刘润桦:这个项目对我来说颇具挑战性,因为这是少有的项目我与他人合作完成并且使用了较不熟练的语言python。借助于CSDN和博客园的网友博客,我从这个项目中学到了大量的python语言的知识。最后,可以与他人一起完成这么一个项目令我十分的高兴,希望下一次可以继续合作。
梁戬希:在这次项目中,我学会了在python中如何处理命令行参数,以便用户可以通过命令行来配置程序,同时熟悉了对文件的读写操作,并且了解了如何使用性能分析工具来分析代码的性能,以找出潜在的性能瓶颈;同时我也遇到了许多难题,比如编程实现对应功能时,要满足数学表达式的各种复杂格式;这耗费了我很长的时间,但这样的挑战也让我的编程能力得到了提高。 -
结对感受
刘润桦:我很高兴与梁戬希同学一起完成这个项目,在一起做这个项目的时候,我们分工明确,目标一致,比较迅速地达到我们做这个项目的预期。梁戬希同学善于使用不同的工具来找到问题的解决方案和善于写出优质的代码,我十分欣赏他代码的编写能力与解决一件事情的毅力。
梁戬希:这次结对项目让我感受到了结对项目是一种极好的知识共享机会,取长补短,一同审查代码使得我们的代码质量得到提升;不同的意见能激发灵感与讨论,使得项目更加的完善;及时的交流与反馈使得代码能够进行及时的调整,不会造成不可逆转的错误;总的来说,我感觉到结对项目比以往的单兵作战有着更高的效率,让编程和完成项目的过程更加地有趣和富有挑战性。