结对编程
这个作业属于哪个课程 | 软件工程 |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 结对编程开发项目 |
成员 | 3118005416刘芊羿 3118005436朱景钊 |
Github链接:https://github.com/comesomemusic/comesomemusic.git | |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 70 |
· Estimate | · 估计这个任务需要多少时间 | 60 | 70 |
Development | 开发 | 1000 | 1210 |
· Analysis | · 需求分析 (包括学习新技术) | 100 | 100 |
· Design Spec | · 生成设计文档 | 100 | 100 |
· Design Review | · 需求分析 (包括学习新技术) | 50 | 50 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 50 | 60 |
· Design | · 具体设计 | 300 | 400 |
· Coding | · 具体编码 | 200 | 300 |
· Code Review | · 代码复审 | 100 | 100 |
· Test | · 测试(自我测试,修改代码,提交修改) | 100 | 100 |
Reporting | 报告 | 500 | 560 |
· Test Repor | · 测试报告 | 200 | 240 |
· Size Measurement | · 计算工作量 | 200 | 220 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 100 | 100 |
· 合计 | 1560 | 1840 |
核心功能实现
题目生成
-
实现思路:
- 因为式子最多三个运算符号,所以使用随机数确定运算符数量
- 根据确定的运算符个数来生成符号并进行连接
- 通过构造增量来进行连接,并将新的表达式进行重复连接
-
流程图
-
代码
# -*- coding: UTF-8 -*-
import math
import sys
import random
import heapq
import re
from fractions import Fraction
import logging
#测试 s="".join print(s)
#约分
def rdOfAFra(n,m):
n=int(n)
m=int(m)
if n>m:
t=n
n=m
m=t
if n==1:
return str(n)+'/'+str(m)
elif n==2 or n==4:
if m%2==0:
return str(n//2)+'/'+str(m//2)
elif m%4==0:
return str(n//4)+'/'+str(m//4)
else :
return str(n)+'/'+str(m)
else :
t=int(n//2)
for i in range(2,t):
while (n%i==0 and m%i==0):
n=n//i
m=m//i
return str(n)+'/'+str(m)
#生产运算数字 n表示范围 k表示类型2、3为整数、1为代分数、0为真分数
def prdctN(k,n):
if (n==1):
k=0
if k>=2:
return str(random.randint(0,n))
elif k==1:
if n==2:
m=1
else:
m=random.randint(1,n-1)
b=random.randint(1,n)
a=random.randint(1,n)
if a==b:
return str(m)
s=rdOfAFra(a,b)
return '('+str(m)+"'"+'('+str(s)+')'')'
elif k==0 :
b=random.randint(1,n)
a=random.randint(1,n)
if a==b:
return str(1)
s=rdOfAFra(a,b)
return '('+s+')'
else :
print("数字类型错误")
#产生运算符 k:0 1 2 3 对应+ - * /
def prdctC(k):
if k==0:
return '+'
elif k==1:
return '-'
elif k==2:
return '*'
elif k==3:
return '/'
else :
print("符号类型错误")
def dlSmPrn(s):
#去除重复括号
lst=list(s)
L=[]#用来储存读取到的符号所在的位置
i=0
while i<len(lst):
if lst[i]=="(":
if i==1:
pass
L.append(i)
while lst[i]==")":#删除重复
j=L.pop()
if(j==len(lst)-1)and L[len(L)-1]==0:
del lst[i+1]
del lst[L.pop()]
while lst[i+1]==')' and(j-1==L[(len(L)-1)]):
del lst[i+1]
i=i-1
j=L.pop()
del lst[j]
else:
pass
i=i+1
i+=1
return ''.join(lst)
#s为没加括号的表达式 n为表达式数字的多少
def prdctPrn(s,n):
lst=list(s)
#随机数为0时产生括号
r=1
while(random.randint(0,2)==0 or r==1):
r=0
st=random.randint(1,n)
lnth=random.randint(2,n-st+2)
if st==1:
lst.insert(0,'(')
i=1
if(lnth>=0):
while(i<len(lst)-2 and lnth>=0):
if lst[i]==" " and (lst[i+1]=="+" or lst[i+1]=="-"or lst[i+1]=="*" or lst[i+1]=="/"or lst[i+1]=='=') and lst[i+2]==" "and st>=0:
if lnth==0:
while(lst[i]!=" "and (lst[i+1]=="+" or lst[i+1]=="-"or lst[i+1]=="*" or lst[i+1]=="/"or lst[i+1]=='=')):
i+=1
lst.insert(i,")")
s="".join(lst)
i+=1
lnth=lnth-1
i+=1
else:
pass
else:
print("右括号生距离错误")
return s
else :
st-=1
i=0
while (i<len(lst)-2):
if lst[i]==" " and (lst[i+1]=="+"or lst[i+1]=="-"or lst[i+1]=="*" or lst[i+1]=="/"or lst[i+1]=='=') and lst[i+2]==" " and st>=0:
st-=1
if st==0:
lst.insert(i+3,'(')
i+=1
if(lnth>=0):
while(i<len(lst)-2 and lnth>=0):
if lst[i]==" " and (lst[i+1]=="+"or lst[i+1]=="-"or lst[i+1]=="*" or lst[i+1]=="/"or lst[i+1]=='=') and lst[i+2]==" "and st>=0:
if lnth==0:
lst.insert(i,")")
i+=1
lnth=lnth-1
i+=1
else:
print("右括号生距离错误")
return s
i+=1
s=''.join(lst)
return s
def prdctE(n=10):
NumOfC=random.randint(1,3)#随机生成符号数
N=NumOfC
s=''
while NumOfC>=0:
NumOfC-=1
C=random.randint(0,3)#随机生成符号
k=random.randint(0,2)
s=s+prdctN(k,n)+' '+prdctC(C)+' '
k=random.randint(0,4)
s=s+prdctN(k,n)+' '+'='+' '
s=prdctPrn(s,N)
s=dlSmPrn(s)
return s
计算结果生成
-
实现思路:
- 通过正则表达式来对式子中的假分数进行替换,同时将分数套上括号
- 使用python自带的eval进行结果运算
- 将得出的结果转化为假分数
- 进行查重以及去除负数
-
流程图
-
代码截图
def do_math(s):
S1=re.sub(r"'",'+',s)
S2=re.sub(r'(\d+/\d+)',r'(\1)',S1)
S3=re.sub(r"=",'',S2)
S4=re.sub(r'(\d+)', r'Fraction("\1")',S3)
try:
answ=eval(S4)
return answ
except Exception as e:
print(e)
return -1
Sanswer=''
Sq=''
d={}
for i in range(1,10000):
s=prdctE(random.randint(1,10))
answ=do_math(s)
while(answ in d.keys() or int(answ)<=0) :
s=prdctE(random.randint(1,10))
answ=do_math(s)
else :
a=int(answ)
answ=answ-a
if(a==0 or answ==0):
d[answ]=0
Sq=Sq+str(i)+'.'+s+"\n"
Sanswer=Sanswer+str(i)+'.'+str(answ)+"\n"
else :
answ=str(a)+"'"+str(answ)
d[answ]=0
Sq=Sq+str(i)+'.'+s+"\n"
Sanswer=Sanswer+str(i)+'.'+str(answ)+"\n"
命令行运行
生成10000个表达式截图
答案与式子文本截图
使用-r -n运行并除零异常处理截图
函数说明
单元测试
-进行了答案生成的代码调试,共十条用例,截图如下:
性能分析
性能分析截图
项目小结
- 刘芊羿结对感受:
初次进行结对编程,获益良多,感受到了团体合作的力量,在很多细节方面可以发现并探讨。
比起个人编程更为方便快捷,且能发现自己的不足 - 朱景钊结对感受:
两人合作更容易发现问题,解决问题也更加方便。