软工作业3结对项目-曾乐儿 廖婉仪
作业要求
这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 结对项目-四则运算 |
这个作业的目标 | 1、完成PSP表格。2、完成“小学四则运算算法”的设计并进行测试。3、代码签入Github中。 4、编写博客记录。 |
Github链接 | github链接 |
姓名学号 | 曾乐儿3221004684 廖婉仪3221005329 |
设计报告
一、需求分析
- 1、题目:实现一个自动生成小学四则运算题目的命令行程序(也可以用图像界面,具有相似功能)
- 2、说明:
自然数:0,1,2,...。
自然数:0, 1, 2, …。
真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
运算符:+, −, ×, ÷。
括号:(, )。
等号:=。
分隔符:空格(用于四则运算符和等号前后)。
算术表达式:
e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),
其中e, e1和e2为表达式,n为自然数或真分数。
四则运算题目:e = ,其中e为算术表达式。
题目分析
- 需要传入参数n、r控制题目个数和数值范围
- 在生成的题目中,运算符最多三个,结果不能为负数,分数必须要真分数,题目不能重复
- 将生成的题目、答案、验证结果保存在文件中。
思路分析
1、使用随机数生成2到4个运算的数值,此时全都以分数形式保存,再随机生成对应数量运算符号
2、计算题目时,先乘除后加减,判断结果答案是否唯一,如果是,则生成的题目中一定没有重复的。然后将结果约分。
3、将题目、答案、验证结果保存在文件中
流程分析图
二、设计实现过程
-
在函数main中输入参数n、r,使用random随机生成数确定计算的数的个数,再随机生成具体的数,以分数的形式保存
-
创建计算答案的函数
def calculatorFunction(mylist, cal)
,把答案进行约分def reductionFunction(list_re)
,设计打印题目、打印答案的函数def printFunction(mylist, cal, cnt)``def printAnswer(ans, cnt)
-
验证答案的正确性,在函数在
answerJudge()
中读取答案文件并验证,并设计calcutalorFileExercise
函数读取题目文件并在calcuta
中计算结果
具体设计
关键代码
在主函数mian中,运用随机生成数来生成计算数字和运算符号
r = int(input("请输入您所需要控制的数值(自然数、真分数和真分数分母)的范围:")) # r控制题目中数值(自然数、真分数和真分数分母)的范围
cnt = 1 # 题目计数器
while cnt <= n:
# -----定义参数-----
# num用来确定需要运算的数字的个数
num = random.randint(2, 4)
mylist = [[] for _ in range(num)] # 数据结构,用来存储需要运算的数字
cal = [] # 数据结构,用于存储运算符
# 定义运算符
operators = ['+', '-', '×', '÷']
for i in range(num - 1):
cal.append(random.choice(operators))
# 定义运算数字(用分数表示)
for i in range(num):
u = random.randint(0, r) # 分子
d = random.randint(1, r) # 分母
while u / d > r: # 保证这个数小于r
u = random.randint(0, r)
d = random.randint(1, r)
mylist[i].append(u)
mylist[i].append(d)
计算题目部分
while cnt < len(cal_cal):
if cal_cal[cnt] == '×' or cal_cal[cnt] == '÷':
# 计算答案的分子和分母
u1 = cal_list[cnt][0]
d1 = cal_list[cnt][1]
u2 = cal_list[cnt + 1][0]
d2 = cal_list[cnt + 1][1]
if cal_cal[cnt] == '×': # 计算乘法
ansu = u1 * u2
ansd = d1 * d2
elif cal_cal[cnt] == '÷': # 计算除法
ansu = u1 * d2
ansd = d1 * u2
# 将答案的分子和分母存储在列表中
ans = [ansu, ansd]
# 删除运算当中已经计算的部分
del cal_cal[cnt]
del cal_list[cnt + 1]
del cal_list[cnt]
# 插入计算的答案
cal_list.insert(cnt, ans)
else:
cnt = cnt + 1
# 再计算加减法
cnt = 0 # 初始化计算器
while cnt < len(cal_cal):
u1 = cal_list[cnt][0]
d1 = cal_list[cnt][1]
u2 = cal_list[cnt + 1][0]
d2 = cal_list[cnt + 1][1]
if cal_cal[cnt] == '+': # 计算加法
ansu = u1 * d2 + d1 * u2
ansd = d1 * d2
elif cal_cal[cnt] == '-': # 计算减法
ansu = u1 * d2 - d1 * u2
ansd = d1 * d2
# 将答案的分子和分母存储在列表中
ans = [ansu, ansd]
# 删除运算当中已经计算的部分
del cal_cal[cnt]
del cal_list[cnt + 1]
del cal_list[cnt]
# 插入计算的答案
cal_list.insert(cnt, ans)
ans1 = [[ansu, ansd]]
验证答案,使用正则匹配判断答案是否相同
str1=list_an[i-1]
str2=list_zuihou[i-1]
#使用正则表达式来比较两个字符串的大小
if compare_strings(str1,str2) == False:
WCount += 1
Wrong.append(i)
else:
CCount += 1
Correct.append(i)
separator = ', '
Wrong = separator.join((str(x) for x in Wrong))
Correct = separator.join((str(x) for x in Correct))
pattern = r'\d+'
digits1 = re.findall(pattern, str1)
digits2 = re.findall(pattern, str2)
return digits1 == digits2
性能分析
- 对生成题目计算答案并保存的进行性能分析,指定在10范围内生成10道题目
统计信息:
覆盖率:
测试运算
单元测试
- 测试计算函数的正确性
def test_calcutalor(self):
strlist1=[
[9,4],
[8,4],
[2,4]
]
callist1=['+','÷']
strlist2 = [
[4, 3],
[9, 7],
[3, 3]
]
callist2 = ['+', '×']
answer1=calclass.calculatorFunction(strlist1,callist1)
answer2=calclass.calculatorFunction(strlist2,callist2)
print(answer1,answer2)
- 测试验证答案是否正确的
def test_answeJudge(self):
a,b,c,d=calclass.answerJudge()
print("正确的题目数:",c)
print(a)
print('\n')
print("错误的题目数:", d)
print(b)
- 测试题目的计算答案
def test_calcuta(self):
str1=['4','÷','4','+',"4'7/6"]
print(calclass.calcuta(str1))
- 测试验证结果的保存
def test_saveJudge(self):
C=[1,2,3,4,5]
W=[6,7,8,9,10]
Ccount=5
Wcount=5
calclass.saveJudge(C,W,Ccount,Wcount)
- 验证将数转换为分数
def test_tofra(self):
strNum1="5/8"
strNum2="1'5/8"
print(calclass.tofra(strNum1),calclass.tofra(strNum2))
- 测试生成100000道题目
#测试是否能生成10000道题目
def test_main(self):
calclass.main()
- 测试比较答案
def test_compare(self):
str1=['10','2',"1'4/7","4'8/8"]
str2=['10','1',"1'4/7","4'1/8"]
for i in range(4):
if(calclass.compare_strings(str1[i],str2[i]))==True:
print("相同")
else:
print("不相同")
测试结果
项目总结
本次结对编程体现了协作交流的重要性。在项目分析时,有效的沟通是促进合作成功的基础。
在分工合作时,能够很好的做到取长补短,充分发挥2个人的优势,并且能够更好地推进项目,实现项目的开发和优化。
PSP表格记录
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时 |
---|---|---|---|
Planning | 计划 | 120 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 120 | 30 |
Development | 开发 | 800 | 835 |
· Analysis | · 需求分析 (包括学习新技术) | 100 | 100 |
· Design Spec | · 生成设计文档 | 100 | 75 |
· Design Review | · 设计复审 | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 15 |
· Design | · 具体设计 | 120 | 150 |
· Coding | · 具体编码 | 240 | 300 |
· Code Review | · 代码复审 | 100 | 120 |
· Test | · 测试(自我测试,修改代码,提交修改) | 90 | 45 |
Reporting | 报告 | 200 | 115 |
· Test Repor | · 测试报告 | 120 | 75 |
· Size Measurement | · 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 20 |
· 合计 | 1120 | 980 |