软工第三次作业
王嘉慧 3223004385
王腾 3123004366
GitHub项目地址:https://github.com/Wangjiahui1266/compute
| 这个作业属于哪个课程 | <班级的链接> |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13470 |
| 这个作业的目标 | 熟悉小组合作的形式并在该形式中思考团队完成开发任务时需考虑的具体细节 |
PSP表格
| PSP阶段 | 预估时间(分钟) | 实际时间(分钟) |
|---|---|---|
| 计划 | 30 | 25 |
| · 需求分析 | 15 | 10 |
| · 技术选型 | 10 | 10 |
| · 制定计划 | 5 | 5 |
| 开发 | 210 | 245 |
| · 系统设计 | 30 | 35 |
| · 代码实现 | 120 | 150 |
| · 测试调试 | 60 | 60 |
| 报告 | 60 | 50 |
| · 撰写文档 | 40 | 35 |
| · 性能分析 | 20 | 15 |
| 总计 | 300 | 320 |
效能分析
性能改进思路:
1.表达式生成算法优化:从递归生成改为迭代生成,减少函数调用开销
2.去重机制优化:使用哈希集合存储表达式签名,提高查找效率
3.验证逻辑简化:避免重复计算,提前终止无效表达式的生成
4.内存管理:及时清理不再使用的数据结构,减少内存占用
性能分析结果
通过cProfile进行性能分析,发现主要耗时函数如下:
| 函数 | 耗时百分比 |
|---|---|
| validate_expression | 35% 时间消耗 |
| normalize_expression | 25% 时间消耗 |
| generate_simple_expression | 20% 时间消耗 |
| calculate_expression | 15% 时间消耗 |
设计实现过程
类设计:
class ExpressionGenerator:
def init(self, range_num)
def generate_number(self)
def format_number(self, num)
def parse_number(self, num_str)
def calculate_expression(self, expr)
def generate_simple_expression(self)
def validate_expression(self, expr)
def normalize_expression(self, expr)
def normalize_simple_expr(self, expr)
def generate_expression(self)
关键函数流程图:

代码说明
核心代码解析
def generate_simple_expression(self):
"""生成简单的表达式(1-3个运算符)"""
num_operators = random.randint(1, 3)
numbers = [self.generate_number() for _ in range(num_operators + 1)]
operators = [random.choice(['+', '-', '×', '÷']) for _ in range(num_operators)]
# 构建表达式
expr_parts = []
for i in range(num_operators):
expr_parts.append(self.format_number(numbers[i]))
expr_parts.append(operators[i])
expr_parts.append(self.format_number(numbers[-1]))
# 随机添加括号
if num_operators > 1 and random.random() < 0.5:
pos = random.randint(0, num_operators - 1)
if pos == 0:
expr_parts = ['('] + expr_parts[:3] + [')'] + expr_parts[3:]
else:
expr_parts = expr_parts[:pos*2] + ['('] + expr_parts[pos*2:pos*2+3] + [')'] + expr_parts[pos*2+3:]
return ' '.join(expr_parts)
思路:随机生成1-3个运算符的表达式,然后随机添加括号,确保表达式的多样性。
def validate_expression(self, expr):
"""验证表达式是否满足要求"""
try:
# 检查运算符数量
operators = [op for op in expr.split() if op in ['+', '-', '×', '÷']]
if len(operators) > 3:
return False
# 计算表达式值
result = self.calculate_expression(expr)
if result is None or result < 0:
return False
# 检查减法和除法
parts = expr.split()
for i in range(len(parts) - 1):
if parts[i] in ['+', '-', '×', '÷', '(', ')']:
continue
if i + 1 < len(parts) and parts[i + 1] == '-':
# 检查减法:左操作数 >= 右操作数
left = self.parse_number(parts[i])
right = self.parse_number(parts[i + 2])
if left < right:
return False
if i + 1 < len(parts) and parts[i + 1] == '÷':
# 检查除法:结果应该是真分数
left = self.parse_number(parts[i])
right = self.parse_number(parts[i + 2])
if right == 0:
return False
# 检查除法结果是否为真分数
division_result = left / right
if division_result.denominator == 1: # 整数结果
return False
return True
except:
return False
思路:全面验证表达式是否满足所有要求,包括运算符数量、计算结果、减法和除法的特殊要求。
测试运行
测试用例:
1.基本功能测试
python program.py -n 5 -r 10
验证:生成5道10以内的题目,检查文件是否正确生成
2.边界测试
python program.py -n 1 -r 1
验证:最小数值范围测试
3.大规模测试
python program.py -n 100 -r 20
验证:生成100道题目,测试程序稳定性
4.批改功能测试
python program.py -e Exercises.txt -a Answers.txt
验证:使用生成的题目和答案进行批改
5.错误参数测试
python program.py -n 10
验证:缺少必要参数时应报错
6.负值测试
python program.py -n -5 -r 10
验证:处理非法参数
7.文件不存在测试
python program.py -e nonexistent.txt -a Answers.txt
验证:处理文件不存在情况
8.性能测试
python program.py -n 1000 -r 50
验证:测试程序处理大量题目的能力
9.格式验证测试
手动创建测试文件,验证格式处理
10.重复题目测试
生成大量题目,验证去重功能
项目总结
成功之处
1.功能完整性:成功实现了所有核心需求,包括题目生成、答案计算、批改统计等功能
2.数学准确性:使用Fraction类确保分数运算的精确性,避免了浮点数误差
3.健壮性:完善的错误处理和参数验证,程序稳定性良好
4.扩展性:模块化设计便于后续功能扩展和维护
经验教训
1.设计先行:初期未充分设计表达式生成算法,导致多次重构
2.测试驱动:应更早建立完整的测试用例,避免后期调试困难
3.性能考量:去重机制初期效率较低,通过优化标准化算法显著提升性能
4.用户体验:命令行参数验证和帮助信息对用户友好性很重要
改进方向
1.算法优化:表达式生成算法仍有优化空间,可减少无效尝试
2.并发处理:对于大规模题目生成可引入并行计算
3.界面增强:考虑添加图形界面版本
4.题目难度分级:可根据年级设置不同的难度级别
核心收获:通过此项目,深刻体会到良好的架构设计比急于编码更重要,充分的测试是质量的保障。
浙公网安备 33010602011771号