结对项目
这个作业属于哪个课程 | 这个作业要求在哪里 | 这个作业的目标 |
---|---|---|
软件工程导论 | 结对项目 | 熟悉PSP流程,学习项目协作开发过程 |
作者:薛考瑶3223004258 苏雨童3223004255
GiuHub:https://github.com/XueKaoyao/pairproject
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 60 |
· Estimate | ·估计这个任务需要多少开发时间 | 350 | 540 |
Development | 开发 | 360 | 540 |
· Analysis | ·需求分析(包括学习新技术) | 30 | 30 |
· Design Spec | ·生成设计文档 | 30 | 60 |
· Design Review | ·设计复审 | 10 | 20 |
· Coding Standard | ·代码规范(为目前的开发制定合适的规范) | 10 | 10 |
·Design | ·具体设计 | 50 | 70 |
· Coding | ·具体编码 | 110 | 140 |
· Code Review | ·代码复审 | 20 | 40 |
· Test | ·测试(自我测试,修改代码,提交代码) | 20 | 60 |
Reporting | 报告 | 40 | 40 |
·Test Repor | 测试报告 | 50 | 20 |
· Size Measurement | ·计算工作量 | 5 | 10 |
· Postmortem & Process Improvement Plan | ·事后总结 | 20 | 30 |
·合计 | 1135 | 1670 |
效能分析
生成题目和答案文件:
- 性能总体良好:所有关键操作如随机数生成、字符串操作、文件操作等都非常高效,几乎没有时间开销。
- 函数调用高效:即使某些函数调用了多次(如随机数生成函数等),它们的执行时间依然非常短,未对性能造成影响。
- exec 函数略微慢:exec 方法的调用时间为 0.001 秒,虽然时间消耗较小,但它通常较慢,还需考虑优化或避免在频繁调用的地方使用。
统计对错结果:
- 整体来看,性能分析结果显示程序中的函数调用没有显著的时间消耗。
设计实现过程
各函数功能
generate_fraction
:生成真分数,保证分母不为1
generate_expression
:生成四则运算表达式
evaluate_expression
:计算表达式的结果
generate_questions_and_answers
:生成题目和答案
write_to_files
:把题目和答案写入文件中
grade_answers
:统计答案对错结果
函数调用流程图
main 函数调用:
generate_questions_and_answers 函数内部调用:
代码说明
展示出项目关键代码,并解释思路与注释说明。(4分)
生成四则运算表达式函数
使用一个 for 循环迭代 num_operations 次,每次循环执行以下操作:
- 从 operators 列表中随机选择一个运算符 operator。
- 如果选择的运算符是 '/'(除法),则调用函数 generate_fraction 来生成一个表示真分数的表达式。
- 如果选择的运算符不是 '/',则直接在 expression 后面添加一个由空格分隔的运算符和一个新的随机操作数。
def generate_expression(range_limit, num_operations):
# 生成四则运算表达式
operators = ['+', '-', '*', '/']
expression = str(random.randint(0, range_limit - 1)) # 起始为一个自然数
for _ in range(num_operations):
operator = random.choice(operators)
if operator == '/':
# 生成除法表达式时,需要确保其结果是一个真分数
expression += generate_fraction(operator, range_limit - 1, range_limit - 1)
else:
expression += f" {operator} {random.randint(0, range_limit - 1)}"
return expression
统计答案对错结果函数
- 使用 with open 语句同时打开 exercise_file 和 answer_file,分别以只读模式读取其内容。
- 初始化结果列表
- 使用 enumerate 结合 zip(questions, answers) 遍历题目和答案的每一对,同时获取索引 i。
- 使用 strip() 去除题目字符串的前后空白,并使用 replace(" =", "") 去除题目中的等号,以便进行表达式求值。接着调用函数 evaluate_expression 来计算题目的正确答案。比较计算出的正确答案与所提供的答案,如果两者匹配,将题目编号添加到 correct 列表;如果不匹配,将题目编号添加到 wrong 列表。
def grade_answers(exercise_file, answer_file):
# 根据给定的题目文件和答案文件检查正确答案
with open(exercise_file, "r") as f_questions, open(answer_file, "r") as f_answers:
questions = f_questions.readlines()
answers = f_answers.readlines()
correct = []
wrong = []
for i, (question, answer) in enumerate(zip(questions, answers)):
question = question.strip().replace(" =", "")
correct_answer = evaluate_expression(question)
if correct_answer == answer.strip():
correct.append(i + 1)
else:
wrong.append(i + 1)
with open("Grade.txt", "w") 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")
测试运行
题目 | 正确答案 | 所提供答案 | 评分结果 |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
项目小结
薛考瑶:完成本次结对项目过程中遇到不少分歧,包括对编程语言的选择、程序的设计等等,但是通过借鉴大量网上的项目实现以及我们二人的头脑风暴之后,最终意见达成一致,并且很快地完成任务。队友很有自己的想法,表达沟通能力和思维能力都很强,和她合作十分愉快!!
苏雨童:本次结对项目让我认识到了队友之间沟通的重要性,项目的每一个环节都需要双方的参与。结对编程或设计可以减少错误,因为两个人一起审查代码或设计方案时更容易发现问题。队友非常负责非常可靠,人美心善好说话,专业能力十分过硬,业务能力十分优秀,我要和她做一辈子软件!