项目 内容
班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST
这个作业要求链接 https://www.cnblogs.com/nwnu-daizh/p/14604444.html
我的课程学习目标 1.体验软件项目开发中的两人合作,练习结对编程(Pair programming)
2.掌握Github协作开发程序的操作方法
这个作业在哪些方面帮助我实现学习目标 1.通过阅读《现代软件工程—构建之法》相关内容,对代码风格规范、代码设计规范、代码复审以及结对编程有了一定的认识和掌握
2.通过复审结对方代码并通过github的Fork、Clone、Push、Pull request、Merge pull request等操作对其个人项目仓库的源码进行合作修改,掌握了Github协作开发程序的操作方法
3.以结对编程的方式,共同设计开发出一款D{0-1}KP 实例数据集算法实验平台,对结对编程有了更深刻的体验与理解
结对方学号-姓名 201871030137-杨钦颖
结对方本次博客作业链接 https://www.cnblogs.com/YQY128/p/14655949.html
本项目Github的仓库链接地址 https://github.com/YQY128/SoftwareEngineering/tree/main/D{0-1}KP 实例数据集算法实验平台

任务1:

阅读《现代软件工程—构建之法》第3-4章内容,理解并掌握代码风格规范、代码设计规范、代码复审、结对编程概念

  • 代码风格规范

    代码风格的原则是:简明,易读,无二义性。

代码风格规范主要包含这些方面:缩进、行宽、括号、断行与空白的{}行、分行、命名、下划线问题、大小写问题、注释等。

  • 代码设计规范

    代码设计规范不光是程序书写的格式问题,而且牵涉到程序设计、模块之间的关系、设计模式等方方面面。

代码设计规范主要包含这些方面:函数、goto、错误处理、如何处理C++的类等。

  • 代码复审

    代码复审的定义:看代码是否在“代码规范”的框架内正确地解决了问题。

    复审的形式

    名 称 形 式 目 的
    自我复审 自己 vs. 自己 用同伴复审的标准来要求自己。不一定最有效,因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处
    同伴复审 复审者 vs. 开发者 简便易行
    团队复审 团队 vs. 开发者 有比较严格的规定和流程,用于关键的代码,以及复审后不再更新的代码。覆盖率高——有很多双眼睛盯着程序。但是有可能效率不高(全体人员都要到会)
  • 结对编程

    在结对编程模式下,一对程序员肩并肩地、平等地、互补地进行开发工作。两个程序员并排坐在一台电脑前,面对同一个显示器,使用同一个键盘,同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起单元测试,一起集成测试,一起写文档等。

任务2:

两两自由结对,对结对方《实验二 软件工程个人项目》的项目成果进行评价

  • 结对方博客链接

    https://www.cnblogs.com/YQY128/p/14581570.html

  • 结对方Github项目仓库链接

    https://github.com/YQY128/SoftwareEngineering/tree/main/折扣01背包

  • 博客评论

    • 从博文结构来看,排版简洁清晰,很清楚地展现了各部分的内容,对读者而言是友好的。

    • 从博文内容来看,基本完成了项目所要求完成的任务,任务3的功能实现也比较完善,可以看出来博主是有在认真完成这项作业的。不过,博主对总结中要求的“模块化”原则这一点没有总结出来,另外,代码展示部分也缺少必要的一些注释,博主可以再完善一下。

    • 从博文结构与PSP中“任务内容”列的关系来看,博主将大部分时间投入到具体编码以及测试中,这也的确是现阶段的我们需要花费较多时间的环节,另外,开发部分实际花费的时间要比预估的时间少一些,博主在完成任务时效率应该还是不错的。

    • 关于PSP中“计划共完成需要的时间”与“实际完成需要的时间”两列数据的差异化分析与原因探究,这部分没有很好地完成,希望博主可以后续完善一下,在发现问题,分析原因中继续成长进步。

  • 代码核查表

    • 概要部分

      1. 代码基本符合需求
      2. 代码设计有周全的考虑
      3. 代码可读性还不错
      4. 代码的每一行都执行并检查过了
    • 设计规范部分

      1. 代码没有依赖于某一平台,不会影响将来的移植
      2. 没有无用的代码可以清除
    • 代码规范部分
         修改的部分符合代码标准和风格

    • 具体代码部分

      1. 没有对错误进行处理;对于调用的外部函数,没有检查返回值或处理异常
      2. 参数传递没有错误,字符串是以0开始计数
      3. 没有使用断言(Assert)来保证我们认为不变的条件真的满足
      4. 数据结构中没有无用的元素
    • 效能
         代码的效能一般,数据量比较小时运行较快,但是当数据量较大时耗时较多

    • 可读性
         代码可读性不错,该有注释的地方基本做了注释

  • 结对方项目仓库中的Fork、Clone、Push、Pull request、Merge pull request日志数据

要想将别人的项目clone 到本地,需要下载、安装和配置Git。Git负责用户在计算机上本地发生的、与GitHub有关的所有内容。

下载并安装最新版本的Git

以下是部分配置操作截图,详细可参考这篇博文对Git进行安装、配置。

获取公钥

将公钥添加到Github管理平台

对Git进行环境配置

  • Fork:将别人发布的项目复制,相当于一个分支;项目复制到自己的github中,于是本地就有了一个仓库。

    fork成功后即可在自己的github中看到复制的仓库:

  • Clone:从自己的github上把fork过来的项目复制到本地,这样本地就有了一个项目。

    在本地新建一个MyGit文件夹,将项目文件clone到该文件夹:

  • Push:将本地项目进行修改开发后,同步到你的github上的仓库中。

    在下载下来的本地项目中进行修改,通过“git add”将修改后的文件添加至队列,再通过“git commit”提交本次修改:


  通过“git push”将修改的版本提交至github账户:

  • Pull request:把自己github中的已经修改的内容申请同步到最初那个开发者的项目中。

    “push”之后在github中即可看到修改的记录,点击右上方”Pull request“即可提交请求:

  • Merge pull request:最初的开发者同意你的修改,将其合并到自己的项目中。

    对方同意之后,即可在对方github上看到对项目的修改:

任务3:

采用两人结对编程方式,设计开发一款D{0-1}KP 实例数据集算法实验平台

  • 需求分析陈述

    • 将实验二任务3的功能嵌入平台,作为平台的基础功能
    • D{0-1}KP 实例数据集需存储在数据库
    • 动态嵌入任何一个有效的D{0-1}KP 实例求解算法,并保存算法实验日志数据
    • 人机交互界面要求为GUI界面
    • 设计遗传算法求解D{0-1}KP,并利用此算法测试要求
  • 软件设计说明

    使用python语言来做GUI界面是比较方便的,故软件使用python语言开发。在数据库存储方面,使用SQLite实现数据库存储功能。

  • 软件实现及核心功能代码展示

    • 软件实现

      软件从整体上分为三个窗口类:MyFrame、MyFrame2、MyFrame3:

      1. MyFrame用于获取用户想要读取的文件,输入文件序号,点击按钮后,读取输出的序号,判断输入序号是否合法,弹出提示框,如果读取成功则调用MyFrame2。
      2. MyFrame2用于获取用户想要读取文件中的哪组数据,类中功能与MyFrame类似,如果读取成功则调用MyFrame3。
      3. MyFrame3是功能实现比较集中的一个类。

      MyFrame3中实现的功能有:

      1. 通过函数CreateDataBase(self)创建数据库,并且将指定的文件数据存放至数据库中创建的表中。
      2. 对读取道德文件数据进行编号,并且显示数据.
      3. 对获取到的数据按项集中的第三项物品的价值/重量比进行排序。
      4. 通过bag(self,n,c,w,v)函数实现动态规划算法求解D{0-1}KP问题,并显示运行时间。
      5. 实现散点图的绘制。
      6. 关于遗传算法,其主要的实现函数有:
        init(self,N,n)用来初始化,N为种群规模,n为染色体长度
        fitness(self,C,N,n,W,V,w)为评估函数
        best_x(self,F,S,N)为适应值函数
        rate(self,x)计算比率
        chose(self,p, X, m, n)用来选择
        match(self,X, m, n, p)用来交配
        vari(self,X, m, n, p)用来变异
    • 核心功能代码展示

    # 创建数据库
    def CreateDataBase(self):
        global i
        global d
        global cubage   # 背包最大容量
        global profit   # 物品价值
        global weight   # 物品重量
        global pw       # 物品价值/重量比

        # 连接到SQLite数据库,数据库文件是mrsoft.db
        conn = sqlite3.connect('mrsoft.db')
        cursor = conn.cursor()
        # 如果表已经存在则删除
        cursor.execute('DROP TABLE IF EXISTS user')
        # 如果表不存在则创建表
        cursor.execute('create table if not exists user (num int(10) primary key,profit int(20), weight int(20))')
        cubage[i] = max(list(map(int,re.findall(r'\d+',line[i*8+3]))))
        profit[i] = list(map(int,re.findall(r'\d+',line[i*8+5])))
        weight[i] = list(map(int,re.findall(r'\d+',line[i*8+7])))
        pw[i] = list(map(lambda x:x[0]/x[1],zip(profit[i],weight[i])))
        # 往表中插入数据
        for j in range(0,d):
            cursor.execute('insert into user (num,profit,weight) values ("%d","%d","%d")'%(j,profit[i][j],weight[i][j]))
        cursor.execute('select * from user')
        result=cursor.fetchall()

        # 关闭游标
        cursor.close()
        # 提交事务
        conn.commit()
        # 关闭Connection
        conn.close()

        return result
class MyFrame3(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, '有效数据', size=(800, 800))
        # 遗传算法
        start2 = time.perf_counter()
        heigh = heigh+70
        m = 32       # 规模
        N = 500      # 迭代次数
        Pc = 0.8     # 交配概率
        Pm = 0.05    # 变异概率
        V =profit[i] # 物品价值
        W =weight[i] # 物品重量
        n = len(W)   # 染色体长度
        w = cubage[i]  # 背包最大容量

        C = self.init(m, n)
        S,F  = self.fitness(C,m,n,W,V,w)
        B ,y = self.best_x(F,S,m)
        Y =[y]
        for i in range(N):
            p = self.rate(F)
            C = self.chose(p, C, m, n)
            C = self.match(C, m, n, Pc)
            C = self.vari(C, m, n, Pm)
            S, F = self.fitness(C, m, n, W, V, w)
            B1, y1 = self.best_x(F, S, m)
            if y1 > y:
                y = y1
            Y.append(y)
            
        wx.StaticText(self.panel,label='遗传算法:', pos=(500,heigh))
        heigh = heigh+30
        wx.StaticText(self.panel,label='最大价值为:%d'%(y), pos=(500,heigh))
                   
    # 初始化,N为种群规模,n为染色体长度
    def init(self,N,n):
        C = []
        for i in range(N):
            c = []
            for j in range(n):
                a = np.random.randint(0,2)
                c.append(a)
            C.append(c)
        return C

    # 评估函数
    # x(i)取值为1表示被选中,取值为0表示未被选中
    # w(i)表示各个分量的重量,v(i)表示各个分量的价值,w表示最大承受重量
    def fitness(self,C,N,n,W,V,w):
        S = []     # 用于存储被选中的下标
        F = []     # 用于存放当前该个体的最大价值
        for i in range(N):
            s = []
            h = 0  # 重量
            f = 0  # 价值
            for j in range(n):
                if C[i][j]==1:
                    if h+W[j]<=w:
                        h=h+W[j]
                        f = f+V[j]
                        s.append(j)
            S.append(s)
            F.append(f)
        return S,F

    # 适应值函数,B位返回的种族的基因下标,y为返回的最大值
    def best_x(self,F,S,N):
        y = 0
        x = 0
        B = [0]*N
        for i in range(N):
            if y<F[i]:
                x = i
            y = F[x]
            B = S[x]
        return B,y

    # 计算比率
    def rate(self,x):
        p = [0] * len(x)
        s = 0
        for i in x:
            s += i
        for i in range(len(x)):
            p[i] = x[i] / s
        return p

    # 选择
    def chose(self,p, X, m, n):
        X1 = X
        r = np.random.rand(m)
        for i in range(m):
            k = 0
            for j in range(n):
                k = k + p[j]
                if r[i] <= k:
                    X1[i] = X[j]
                    break
        return X1

    # 交配
    def match(self,X, m, n, p):
        r = np.random.rand(m)
        k = [0] * m
        for i in range(m):
            if r[i] < p:
                k[i] = 1
        u = v = 0
        k[0] = k[0] = 0
        for i in range(m):
            if k[i]:
                if k[u] == 0:
                    u = i
                elif k[v] == 0:
                    v = i
            if k[u] and k[v]:
                # print(u,v)
                q = np.random.randint(n - 1)
                # print(q)
                for i in range(q + 1, n):
                    X[u][i], X[v][i] = X[v][i], X[u][i]
                k[u] = 0
                k[v] = 0
        return X

    # 变异
    def vari(self,X, m, n, p):
        for i in range(m):
           for j in range(n):
                q = np.random.rand()
                if q < p:
                    X[i][j] = np.random.randint(0,2)

        return X
  • 程序运行

    • 选择要读取的文件:

    • 选择要文件中要读取哪一组数据:

    • 读取到的数据存入数据库:

    • 散点图的显示:

    • 遗传算法运行结果(需要注意的是:遗传算法是一种近似最优化算法,它的每个解都是近似最优解,不能保证是全局最优。):

    • 结果存储至txt中:

    • 显示读取到的数据并对其编号,对读取到的数据按项集中的第三项的价值/重量比进行排序,显示动态规划算法以及遗传算法求解后的结果:

  • 项目commit的记录

  • 描述结对的过程,提供两人在讨论、细化和编程时的结对照片
    因为都在一个宿舍,所以聚集在一起来共同完成这个项目是比较方便的,并且比较熟悉,在沟通方面也是顺畅的。最开始是一起分析确定了项目要实现哪一些功能,GUI界面如何呈现,各类功能如何嵌入GUI界面,选择什么语言来编程,大概的方向确定好之后,就开始着手写代码。在编程的过程中,两个人轮流编程,一人编程的时候,另一人帮忙查资料,检查代码中是否有错误,提醒修改,遇到麻烦的地方,两个人一起思考、商量解决办法。
  • 提供此次结对作业的PSP
PSP2.1 任务内容 计划共完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 20 20
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 20 20
Development 开发 1090 1200
Analysis 需求分析 (包括学习新技术) 120 155
Design Spec 生成设计文档 30 20
Design Review 设计复审 (和同事审核设计文档) 20 20
Coding Standard 代码规范 (为目前的开发制定合适的规范) 30 35
Design 具体设计 60 50
Coding 具体编码 600 650
Code Review 代码复审 30 30
Test 测试(自我测试,修改代码,提交修改) 200 240
Reporting 报告 100 100
Test Report 测试报告 30 40
Size Measurement 计算工作量 40 30
Postmortem & Process Improvement Plan 事后总结 ,并提出过程改进计划 30 30
  • 小结感受:两人合作真的能够带来1+1>2的效果吗?通过这次结对合作,请谈谈你的感受和体会
    两人合作是否能够带来1+1>2的效果,取决于两个人之间的沟通是否有效,是否能够朝着共同的目标去各自补充,合作完成任务。对于本次我们组的结对编程,我觉得两个人合作是能带来1+1>2的效果的。
    通过这次结对合作,我觉得对于一个较复杂的任务而言,一个人的能力、掌握的知识毕竟有限,两个人合作编程,能够综合各自掌握的知识,在编码的过程中,两个人轮流编程,互相监督,能够及时发现错误,少走一些不必要的弯路,并且不会的地方,两个人也能够一起讨论对策,提升了编码效率。
    两个人的合作,只要可以有效沟通,是可以很好地达到完成任务、共同进步的效果的。
posted on 2021-04-13 23:41  Y33889  阅读(150)  评论(4编辑  收藏  举报