作业三:结对项目
这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 结对项目 |
这个作业的目标 | 两人合作,根据需求完成一个四则运算题目生成器的开发 |
本次作业的仓库地址 | 项目地址 |
项目成员 | 学号 |
---|---|
陈靖凯 | 3122004856 |
刘曦烨 | 3122004746 |
1. 各模块开发消耗时间(PSP表格)
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 5 |
· Estimate | · 估计这个任务需要多少时间 | 360 | 240 |
Development | 开发 | 335 | 315 |
· Analysis | · 需求分析 (包括学习新技术) | 10 | 5 |
· Design Spec | · 生成设计文档 | 15 | 10 |
· Design Review | · 设计复审 | 5 | 5 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 5 | 5 |
· Design | · 具体设计 | 30 | 30 |
· Coding | · 具体编码 | 180 | 210 |
· Code Review | · 代码复审 | 30 | 40 |
· Test | · 测试(自我测试,修改代码,提交修改) | 10 | 10 |
Reporting | 报告 | 60 | 50 |
· Test Repor | · 测试报告 | 35 | 20 |
· Size Measurement | · 计算工作量 | 10 | 5 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 15 | 15 |
· 合计 | 405 | 370 |
2. 设计过程
根据需求的描述,可以发现项目需要实现的功能大体可以分为三种
- 文件的写入
- 题目的生成
- 答案的计算
对于三个不同的功能,可以设计三个类分别实现对应的功能,在项目中,以上三个类分别为FileManager类、QuestionGenerator类和QuestionCalculator类,并通过主程序调用这些类实现完整的功能
类中各函数调用关系:
QuestionGenerator类
QuestionCalculator类
FileManager类
主程序main与各个类调用关系
3. 效能分析
由于项目开发使用的语言为python,故使用了cProfile库进行性能的分析,通过生成一万个题目,并输出关键函数的各种信息统计如下:
对应列的运行分析信息解释如下:
列表标题 | 解释 |
---|---|
ncalls | 函数调用次数 |
tottime | 在给定函数中花费的总时间(不包括调用子函数的时间) |
percall | tottime除以ncalls的商 |
cumtime | 函数和所有子函数中花费的累积时间(从调用到退出) |
percall | cumtime除以原始调用次数的商 |
filename:lineno(function) | 提供每个函数的各自信息 |
综合以上信息发现,消耗时间最长的是生成题目的函数 |
显然,即使是生成一万个不重复的题目,运行耗时都极低,说明代码运行效率极高,无需优化
4. 关键代码及解释
- 生成题目表达式的关键函数:
def generate_operation(self,max_operand):
operators = ['+', '-', '×', '÷']
num_operators = random.randint(1, 3)
expression = str(random.randint(1, max_operand))
for _ in range(num_operators):
operator = random.choice(operators)
operand = random.randint(1, max_operand)
if operator == '÷':
# 生成真分数
numerator = random.randint(1, operand - 1) if operand > 1 else 1
fraction = Fraction(numerator, operand)
expression += f" {operator} {fraction}"
else:
if operator == '-':
# 避免生成负数
operand = random.randint(1, int(expression.split()[-1]))
expression += f" {operator} {operand}"
return expression
- 计算结果的函数:
def evaluate_expression(expression):
try:
# 将真分数转换为浮点数进行计算
expression = expression.replace('×', '*')
result = eval(expression.replace('÷', '/'))
# 如果结果是浮点数,将其转换为真分数
if isinstance(result, float):
return str(Fraction(result).limit_denominator())
return str(result)
except ZeroDivisionError:
return "Undefined"
5. 测试过程
5.1 单元测试
通过使用pytest库进行单元测试,编写单元测试代码如下:
import pytest
from QuestionGenerator import QuestionGenerator
from QuestionCalculator import *
@pytest.fixture
def question_generator():
return QuestionGenerator()
def test_generate_operation(question_generator):
max_operand = 10
for _ in range(10): # 多次测试以确保随机性
operation = question_generator.generate_operation(max_operand)
assert isinstance(operation, str)
def test_generate_math_questions(question_generator):
num_questions = 5
max_operand = 10
questions = question_generator.generate_math_questions(num_questions, max_operand)
assert len(questions) == num_questions
for question in questions:
assert isinstance(question, str)
@pytest.fixture
def calculator():
return Calculator()
def test_evaluate_expression_fraction_addition(calculator):
expression = "1/2 + 1/3"
result = calculator.evaluate_expression(expression)
assert result == "5/6"
def test_evaluate_expression_integer_division(calculator):
expression = "10 ÷ 2"
result = calculator.evaluate_expression(expression)
assert result == "5"
def test_evaluate_expression_divide_by_zero(calculator):
expression = "5 ÷ 0"
result = calculator.evaluate_expression(expression)
assert result == "Undefined"
def test_calculate_answers(calculator):
questions = ["2 + 2", "3 × 4", "10 ÷ 5"]
expected_answers = ["4", "12", "2"]
answers = calculator.calculate_answers(questions)
assert answers == expected_answers
if __name__ == "__main__":
pytest.main()
测试结果:
5.2 命令行运行测试
输入指令
运行后生成的文件内容
6. 项目小结
本项目作为我们再次一起合作开发的项目,因为我们同时也都是一个工作室的成员,有过一起开发项目的经历
此次合作开发的经历给我们带来的收获有:
- 分工安排上更加明确
- 对项目管理软件使用也比第一次合作开发更加熟练,目前我们都已经熟练掌握了git的基本指令,像什么git clone、git pull、git push之类的基础指令
- 对于项目的需求分析能力也大幅提升,可以更好地将需求转化为要实现的功能