结对编程

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

函数说明

单元测试

-进行了答案生成的代码调试,共十条用例,截图如下:

性能分析

性能分析截图


项目小结

  • 刘芊羿结对感受:
    初次进行结对编程,获益良多,感受到了团体合作的力量,在很多细节方面可以发现并探讨。
    比起个人编程更为方便快捷,且能发现自己的不足
  • 朱景钊结对感受:
    两人合作更容易发现问题,解决问题也更加方便。
posted @ 2020-10-13 01:37  马大叔的门牙  阅读(150)  评论(0编辑  收藏  举报