201971010157-张颖 实验三 结对项目-《{0-1}KP实例数据集算法实验平台》

项目 内容
课程班级博客链接 2019级卓越班
这个作业要求链接 实验三 软件工程结对项目
我的课程学习目标
  1. 体验软件项目开发中的两人合作,练习结对编程(Pair programming)。
  2. 掌握Github协作开发软件的操作方法。
这个作业在哪些方面帮助我实现学习目标
  1. 自学《构建之法》第3、4章的内容,理解并体验了结对编程
  2. 两人一起共同讨论,发现问题并解决问题
  3. 在github对结对方的代码进行一系列的操作
结对方学号-姓名 201971010106-陈玉英
结对方本次博客作业链接 201971010106-陈玉英 实验三 结对项目-《{0-1}KP实例数据集算法实验平台》项目报告
本项目Github的仓库链接地址 https://github.com/xiaokaxi08042/text2

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

代码规范-

  • 代码规范可以分为两个部分:
  1. 代码风格规范-主要是文字上的规定、看似表面文章,实际上非常重要
  2. 代码设计规范-牵扯到程序设计、模块之间的关系、设计模式等方方面面的通用规则

代码风格规范-

  • 代码风格的原则是:简明,易读,无二义性
  1. 缩进:4个空格比tab键更好,tab键在不同的情况下会显示不同的长度,严重干扰阅读体验,4个空格的距离从可读性来说,正好。
  2. 行宽:行宽必须限制,以前有些文档规定的80字符行宽太小,现在可以先定为100字符
  3. 括号:在复杂的条件表达式中,用括号清楚地表示逻辑优先级
  4. 断行与空白的{}行:每个“{”和“}”都独占一行
  5. 分行:不要把多条语句放在一行上,更严格的说,不要把多个变量定义在一行上
  6. 命名:(1)在变量名中不要提到类型或其他语法方面的描述(2)避免过多的描述(3)如果信息可以从上下文中得到,那么此类信息就不必写在变量名中(4)避免可要不可要的修饰词
  7. 下划线:用来分隔变量名字中的作用域标注和变量的语义
  8. 大小写:所有单词的第一个字母都大写(Pascal);第一个单词全部小写,随后单词随Pascal形式
  9. 注释:(1)解释程序做什么,为什么这样做,以及要特别注意的地方(2)复杂的注释应该放在函数头(3)注释要随着程序的修改而不断更新(4)注释应该只用ASCII字符,不要用中文或其他特殊字符

码设计规范-

  • 代码设计规范不光是程序书写的格式问题,而且牵扯到程序设计、模块之间的关系、设计模式等方方面面,这里又有不少内容与具体程序设计语言息息相关,但是也有通用的规则,主要有——
  1. 函数:现代程序设计语言中的绝大部分功能,都在程序 的函数中实现
  2. goto:函数最好有单一的出口,为了达到这一目的,可以使用goto
  3. 错误处理:(1)参数处理(2)断言
  4. 处理c++中的类

代码复审-

  • 定义:看代码是否在代码规范的框架内正确的解决了问题
  • 形式:

名称

形式

目的

自我复审

自己vs.自己

用同伴复审的标准来要求自己。不一定最有效,因为开发者对自己总是过于自信。如果能持之以恒,则对个人有很大好处

同伴复审

复审者vs.开发者

简单易行

团队复审

团队vs.开发者

有比较严格的规定和流程,适用于关键的代码,以及复审后不再更新的代码覆盖率高——有很多双眼睛盯着程序,但效率可能不高

  • 目的:
  1. 找出代码的错误
  2. 发现逻辑错误
  3. 发现算法错误
  4. 发现潜在的错误和回归性错误
  5. 发现可能需要改进的地方
  6. 互相教育开发人员,传授经验
  • 步骤:
  1. 代码必须成功地编译
  2. 程序员必须测试过代码
  3. 程序员必须提供新的代码,以及文件差异分析工具
  4. 在面对面的复审中,一般是开发者控制流程,讲述修改的前因后果。但是复审者有权在任何时候打断叙述,提出自己的意见。
  5. 复审者必须逐一提供反馈意见。
  6. 开发者必须负责让所有的问题都得到满意的解释或解答,或者在TFS中创建爱你新的工作项以确保这些问题会得到处理。
  7. 对于复审的结果,双方必须达成一致的意见
  • 代码复审的核查表:
概要部分
  1. 代码符合需求和规格说明么?
  2. 代码设计是否考虑周全?
  3. 代码可读性如何?
  4. 代码容易维护么?
  5. 代码的每一行都执行并检查过了吗?
设计规范部分
  1. 设计是否遵从已知的设计模式或项目中常用的模式?
  2. 有没有硬编码或字符串/数字等存在?
  3. 代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到 Win64 ) ?
  4. 开发者新写的代码能否用已有的 Library/SDK/Framework 中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现?
  5. 有没有无用的代码可以清除?
代码规范部分

     修改的部分符合代码标准和风格么?

具体代码部分
  1. 有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常?
  2. 参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数?
  3. 边界条件是如何处理的? switch语句的default分支是如何处理的?循环有没有可能出现死循环?
  4. 有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足?
  5. 对资源的利用,是在哪里申请,在哪里释放的?有无可能存在资源泄漏(内存、文件、各种GUI资源、数据库访问的连接等等)?有没有优化的空间?
  6. 数据结构中有没有用不到的元素?
效能
  1. 代码的效能(Performance)如何?最坏的情况是怎样的?
  2. 代码中,特别是循环中是否有明显可优化的部分(C++中反复创建类,C# 中 string的操作是否能用StringBuilder来优化)?
可读性

      代码可读性如何?有没有足够的注释?

可测试性

      代码是否需要更新或创建新的单元测试?针对特定领域的开发(如数据库、网页、多线程等),可以整理专门的核查表。

结对编程-

  • 结编程是一个相互学习、相互磨合的渐进过程。
  • 优点:
  1. 在开发层次,结对编程能提供更好的设计质量和代码质量,良人合作解决问题的能力更强。两人合作,还有相互激励的作用,工程师看到别人的思路和技能,得到实时的讲解,受到激励,从而努力的提高自己的水平,提出更多的创意。
  2. 对开发人员来说,就地工作能带来更多的信心,高质量的产出能带来更高的满足感。
  3. 在企业管理层次上,就地能更有效地交流,相互学习和传递经验、分享知识,能更好地应对人员流动。
  • 两人合作的不同阶段和技巧:
  1. 萌芽阶段
  2. 磨合阶段
  3. 规范阶段
  4. 创造阶段
  5. 解体阶段
  • 影响他人的几种方式:
  1. 断言
  2. 桥梁
  3. 说服
  4. 吸引
  • 评论别人的三种层次:
  1. 最外层:行为和后果
  2. 中间层:习惯与动机
  3. 最内层:本质和固有属性
  • 如何正确地给予反馈:“三明治”办法
  1. 先来一片面包,做好铺垫:强调双方的共同点,从团队共同的愿景讲起,让对方觉得处于一个安全的环境。
  2. 再把肉放上:这时就可以把建设性的意见加工好,加上生菜、佐料等。怎么准备这块肉也有讲究,在提供反馈时,不宜完全沉溺于过去的陈年谷子烂芝麻,给别人做评价,下结论。这样会造成一种“你就是做得不好,我恨你”的情绪。不妨换个角度,展望将来的结果,强调“过去你做得不够,但是我们以后可以做得更好”。在技术团队里,我们的反馈还是要着重于“行为和后果”这一层面,不要贸然深入到“习惯和动机”、“本质”除非情况非常严峻,需要触动别人内心深处,让别人悬崖勒马。
  3. 再来一片面包:呼应开头,鼓励对方把工作做好。

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

  • 符合(2)要求的代码审查表:
概要部分                                       
代码符合需求和规格说明么? 符合
代码设计是否考虑周全? 考虑的不是很周全
代码可读性如何? 可读性好,有注释
代码容易维护么? 层次清晰,模块化不错,遵从基于接口而非实现编程的原则,容易维护
代码的每一行都执行并检查过了吗?
设计规范部分  
设计是否遵从已知的设计模式或项目中常用的模式?
有没有硬编码或字符串/数字等存在? 没有直接将数据嵌入到程序中,没有硬编码存在
代码有没有依赖于某一平台,是否会影响将来的移植(如Win32到 Win64 ) ? 没有依赖于某一平台
开发者新写的代码能否用已有的 Library/SDK/Framework 中的功能实现?在本项目中是否存在类似的功能可以调用而不用全部重新实现? 没有用其功能实现
有没有无用的代码可以清除?
代码规范部分  
修改的部分符合代码标准和风格么? 符合
具体代码部分  
有没有对错误进行处理?对于调用的外部函数,是否检查了返回值或处理了异常? 有对错误进行处理,对于调用的外部函数,检查了返回值没有发现错误
参数传递有无错误,字符串的长度是字节的长度还是字符(可能是单/双字节)的长度,是以0开始计数还是以1开始计数? 参数传递没有错误,字符串的长度是字符的个数,ASCII码下也是字节数,是以0开始计数
边界条件是如何处理的? switch语句的default分支是如何处理的?循环有没有可能出现死循环? 没有用到switch语句,没有出现死循环
有没有使用断言(Assert)来保证我们认为不变的条件真的得到满足? 没有使用断言
对资源的利用,是在哪里申请,在哪里释放的?有无可能存在资源泄漏(内存、文件、各种GUI资源、数据库访问的连接等等)?有没有优化的空间? 因程序功能较为简单,没有使用到GUI资源、数据库等
数据结构中有没有用不到的元素? 没有用不到的元素
效能  
代码的效能(Performance)如何?最坏的情况是怎样的? 效能一般,在数据量很大时会运行较长时间
代码中,特别是循环中是否有明显可优化的部分? 没有明显可优化的部分
可读性  
代码可读性如何?有没有足够的注释? 可读性很好,注释足够
可测试性  
代码是否需要更新或创建新的单元测试?针对特定领域的开发(如数据库、网页、多线程等),可以整理专门的核查表。 实验二的代码没有使用到数据库、网页等的开发
  • 结对方项目仓库中的Fork、Clone、Push、Pull request、Merge pull request日志数据

    Fork 是 Github 上的常用操作之一,不同于 Star,Fork 会将进行 Fork 操作那一刻的仓库代码完全复制到自己的仓库下。Fork 之后,可能会为原仓库添加一个 Feature,之后发起 Pull Request

克隆:

运行:

fork:

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

  • 需求分析陈述——采用“3W”分析法
    • what:需求是什么
    1. 采用动态规划法、贪心算法和回溯算法求解不超过背包容量的最大价值和解向量
    2. 绘制价值重量为横轴,价值为纵轴的数据散点图
    3. 输出的最优解和求解时间可保存为txt文件
    4. 实例数据集存储在数据库
    5. 平台可动态嵌入任何一个有效的{0-1}KP 实例求解算法,并保存算法实验日志数据;
    6. 人机交互界面为GUI界面
    7. 设计遗传算法求解{0-1}KP,并利用此算法测试要求
    • why:为什么会产生这样的需求
    1. 用多种算法解决0-1背包问题
    2. 更好的存储和管理数据
    3. 增加用户的体验感
    • how:如何将需求转化为产品进行后续的价值分析
  • 软件设计说明

  • 软件实现及核心功能代码展示:软件包括哪些类,这些类分别负责什么功能,他们之间的关系怎样?类内有哪些重要的方法,关键的方法是否需要画出流程图?

    遗传算法:遗传算法类似于自然进化,通过作用于染色体上基因寻找好染色体来求解问题。及自然界相似,遗传算法对求解问题本身一无所知,它所需要仅是对算法所产生每个染色体进行评价,并基于适应值来选择染色体,使适应性好染色体有更多繁殖机会。在遗传算法中,通过随机方式产生若干个所求解问题数字编码,即染色体,形成初始群体;通过适应度函数给每个个体一个数值评价,淘汰低适应度个体,选择高适应度个体参加遗传操作,经过遗传操作后个体集合形成下一代新种群。对这个新种群进行下一轮进化。

    算法流程图:

    • 遗传算法-GAType类
class GAType(): # 种群
    def __init__(self, obj_count):
        self.gene = [0 for x in range(0, obj_count, 1)]   # 序列编码 0 / 1
        self.fitness = 0 # 适应度
        self.cho_feq = 0 # choose 选择概率
        self.cum_feq = 0 # cumulative 累积概率
class genetic():
    def __init__(self, value, weight, max_weight):
        self.value = value
        self.weight = weight
        self.max_weight = max_weight
        self.obj_count = len(weight)
        self._gatype = [GAType(self.obj_count) for x in range(0, population_size, 1)]
        self.total_fitness = 0

Back_pack类:(部分功能代码)

 def draw(self):  # 画散点图
        nums_pro = self.str_profit[0:len(self.str_profit)]
        nums_wei = self.str_weight[0:len(self.str_weight)]
        nums_pro = [int(i) for i in nums_pro]
        nums_wei = [int(i) for i in nums_wei]
        df = pd.DataFrame({'profit': nums_pro, 'weight': nums_wei})
        df.plot(kind="scatter", x="weight", y="profit")
        plt.show()
    def DP(self):  # 动态规划算法
        dp = [[[0 for k in range(self.cubage + 5)] for i in range(4)] for j in range(self.size + 5)]  # 三维dp数组
        for k in range(1, self.size + 1):
            for i in range(1, 4):
                for v in range(self.cubage + 1):
                    for j in range(1, 4):
                        dp[k][i][v] = max(dp[k][i][v], dp[k - 1][j][v])
                        if v >= self.items[k - 1].pack[i - 1].weight:
                            dp[k][i][v] = max(dp[k][i][v],dp[k - 1][j][v - self.items[k - 1].pack[i - 1].weight]+self.items[k - 1].pack[i - 1].profit)
                        self.max_val = max(self.max_val, dp[k][i][v])

数据库-sql

config = {
    'host': 'localhost',
    'port': 3306,
    'user': 'root',
    'password': 'root',
    'db': 'dk',
    'charset': 'utf8',
    'cursorclass': pymysql.cursors.DictCursor,
}
  • 程序运行:程序运行时每个功能界面截图。

主页面(GUI界面):

绘制散点图:

    • 数据库存储的数据:

遗传算法:

导出结果文件:

  • 描述结对的过程,提供两人在讨论、细化和编程时的结对照片(非摆拍)。

    理解了领航员和驾驶员两种角色关系:两人都必须参与编码工作,在结对编程中两个人轮流做对方的角色。

    采用了汉堡包法实施项目结对中两个人的沟通:

讨论的步骤总结:

  • 提交源码到Github项目仓库中,编撰两人合作开发遵守共同认可的编码规范,提交项目代码规范文档到Github项目仓库根目录下

 

  • 提供此次结对作业的PSP。
PSP2.1 任务内容 计划完成需要的时间(h) 实际完成需要的时间(h)
Planning 计划 1 1
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 1 1
Development 开发 16.5 21.5
Analysis 需求分析(包括学习新技术) 5 7
Design Spec 生成设计文档 0.5 0.5
Design Review 设计复审 0.5 0.5
Coding Standard 代码规范 0.5 0.5
Design 具体设计 1 1
Coding 具体编码 5 5
Code Review 代码复审 1 2
Test 测试 3 5
Reporting 报告 6.3 9.8
Test Report 测试报告 5 8
Size Measurement 计算工作量 0.3 0.3
Postmortem &Process Improvement Plan 事后总结,并提出过程改进计划 1 1.5
  • 小结感受:两人合作真的能够带来1+1>2的效果吗?通过这次结对合作,请谈谈你的感受和体会。

    通过这次结对实验合作,让我觉得1+1真的大于2,我们两个人在彼此沟通的过程中,都能发现对方没有注意到的问题,这是一个人需要经过很长时间才能意识到的。三人行,必有我师。也就是说每个人都有自己的优劣点以及自己独创的想法。结对完成项目有助于产生不同种想法,从而有助于在决策的时候可以集思广益而产生一种比较好的方案。人无完人,一个人的力量有限,若是个人单打独斗难以把全部事情都做尽做全。但是两人分工合作的话,就会有监督有分工,还能提高自身的效率。

任务4:完成结对项目报告博文作业

 

posted @ 2022-04-04 18:35  小卡西  阅读(79)  评论(3编辑  收藏  举报