结对编程
| 这个作业属于哪个课程 | 软件工程 | 
|---|---|
| 这个作业要求在哪里 | 作业要求 | 
| 这个作业的目标 | 结对编程开发项目 | 
| 成员 | 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运行并除零异常处理截图

函数说明
单元测试
-进行了答案生成的代码调试,共十条用例,截图如下:

性能分析
性能分析截图


项目小结
- 刘芊羿结对感受:
 初次进行结对编程,获益良多,感受到了团体合作的力量,在很多细节方面可以发现并探讨。
 比起个人编程更为方便快捷,且能发现自己的不足
- 朱景钊结对感受:
 两人合作更容易发现问题,解决问题也更加方便。

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号