zoukankan      html  css  js  c++  java
  • 结对编程

    1.编码要求

    (1)Fork github 项目https://github.com/Cherish599/WordCount到自己的仓库,在Github仓库中新建一个以一位同学的学号为名的文件夹,用于建立C#的项目和第二次作业类似。(结对的两人中任意一人的学号都可以)。

    (2)在开始实现程序之前,在PSP表格[附录1]记录下你估计在程序开发各个步骤上耗费的时间,在你实现程序之后,在PSP表格记录下你在程序的各个模块上实际花费的时间。

    (3)使用C#语言实现,C#请使用Visual Studio Community 2017进行开发。

    a)       制定编码规范,可以参考C#语言的规范:简版讨论版。(邹欣老师在讲义“现代软件工程讲义 3 代码规范与代码复审”中所讨论的有关代码规范与代码复审的内容。内容短小精炼,适合快速入门。)

    b)     代码自审并修正,每个人都独立完成了自己的功能任务,对照编码规范,审查修改自己的程序代码并使其符合规范要求。

    c)     代码互审,按照共同制定的编码规范,审查合作伙伴的代码并记录发现的问题。

    d)     合并代码,两人协商,将两部分代码合并,形成初始版本。注意应设计合理的软件结构及模块划分。

    e)     提交的代码要求经过Code Quality Analysis工具的分析并消除所有的警告。

    f)       完成项目的首个版本之后,请使用性能分析工具Studio Profiling Tools来找出代码中的性能瓶颈并进行改进。

    g)     使用Github[附录2]来管理源代码和测试用例,代码有进展即签入Github(至少三次)。签入记录不合理的项目会被助教抽查询问项目细节。

    h)     使用单元测试[附录3]对项目进行测试,并使用插件查看测试分支覆盖率等指标;并写出至少10个测试用例确保你的程序能够正确处理各种情况。

    i)       在完成结对项目后,请按照预第二次作业的方式正确地发起一个Pull Request,并设置标题为本次统一使用的学号。

    2.博客撰写要求

    (1)在文章开头给出结对使用的Github项目地址和结对伙伴的作业地址。(两个人使用同一个)注意:GitHub的地址必须是用于clone的地址即如下图片中的地方获取。(如果不是这个地址,助教就无法批量编译运行你们的程序,出现问题的都会被助教抽中询问详情)

    (2)描述结对的过程,提供非摆拍的两人在讨论的结对照片(一起工作编码时的照片)。

    (3)给出结对的PSP表格。

    a)     解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。

    b)     设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?

    c)     给出你们制定的代码规范或链接,记录你们代码互审的情况,审查的模块名、发现的问题等。

    d)     记录在改进程序性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2017的性能分析工具自动生成),并展示你程序中消耗最大的函数。

    e)     代码说明。展示出项目关键代码,并解释思路与注释说明。

    f)       结合在构建之法中学习到的相关内容与结对项目的实践经历,撰写解决项目的心路历程与收获,以及结对感受,是否1+1>2。

    注:两人都要提交博客,结对共同部分,可在其中一个人的博客给出(另一个人给出链接),不同部分分别写在自己的博客中

    3.项目需求说明

    实现一个命令行程序,不妨称之为wordCount。

    第一步、实现基本功能

    输入文件名以命令行参数传入。例如我们在命令行窗口(cmd)中输入:

    wordCount.exe input.txt

    则会统计input.txt中的以下几个指标

    • 统计文件的字符数:
    • 只需要统计Ascii码,汉字不需考虑
    • 空格,水平制表符,换行符,均算字符
    • 英文字母:A-Z,a-z
    • 字母数字符号:A-Z,a-z,0-9
    • 分割符:空格,非字母数字符号
    • 例:file123是一个单词,123file不是一个单词。file,File和FILE是同一个单词
    • 输出的单词统一为小写格式
    • 统计文件的单词总数,单词:至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。
    • 统计文件的有效行数:任何包含非空白字符的行,都需要统计。
    • 统计文件中各单词的出现次数,最终只输出频率最高的10个。频率相同的单词,优先输出字典序靠前的单词。
    • 按照字典序输出到文件txt:例如,windows95,windows98和windows2000同时出现时,则先输出windows2000
    • 输出的格式为
    ·        characters: number
    ·        words: number
    ·        lines: number
    ·        <word1>: number
    ·        <word2>: number
    ·        ...
     

    第二步、接口封装

    在写了一些代码开胃之后,大家都完成了一份满足基本功能的代码。
    大家的代码都各有特色,如果现在我们要把这个功能放到不同的环境中去(例如,命令行,Windows图形界面程序,网页程序,手机App),就会碰到困难:代码散落在各个函数中,很难剥离出来作为一个独立的模块运行以满足不同的需求。
    同时我们也看到,不同的代码解决不同层面的问题:

    a)     有些是计算数据的(例如统计单词)

    b)     有些是控制输入的(例如ReadLine,图形界面的输入字段)

    c)     有些是数据可视化的(例如WriteLine)

    d)     有些则更为特殊,是架构相关的(例如main函数,并不是所有的程序都需要某个特定格式的main)

    这些代码的种类不同,混杂在一起对于后期的维护扩展很不友好,所以它们的组织结构就需要精心的整理和优化。
    我们希望把基本功能里的:

    a)     统计字符数

    b)     统计单词数

    c)     统计最多的10个单词及其词频

    这三个功能独立出来,成为一个独立的模块(class library, DLL, 或其它),这样的话,命令行和GUI的程序都能使用同一份代码。为了方便起见,我们称之为计算核心"Core模块",这个模块至少可以在几个地方使用:

    a)     命令行测试程序使用

    b)     在单元测试框架下使用

    c)     与数据可视化部分结合使用

    把计算核心在单元测试框架中做过完备的测试后,我们就可以在算法层级保证了这个模块的正确性。
    但我们知道软件并非只有计算核心,实际的软件是交付给最终用户的软件,除了计算核心外,还需要有一定的界面和必要的辅助功能。
    这个Core模块和使用它的其他模块之间则要通过一定的API来交流。
    API应该怎么设计呢?
    为了方便起见,我们可以从下面的最简单的接口开始(仅举例,你的代码里可能没有这个函数):

    public int countChar(String path)

    这个函数表示输入path文件路径字符串,返回这个文件的字符数。
    假设我们的Core里封装了这个接口,那么我们的测试程序可以是这样:

    String path = "input.txt";
     
    int count = 100;
     
    Assert(countChar(in) == count);

    当然,这样的测试程序并不充分,希望大家测试时不要像这样偷懒。

    第三步、增加新功能

    在第三步中,我们希望各位在第一步的基础上,添加一些新的功能:

    a)     词组统计:能统计文件夹中指定长度的词组的词频

    b)     自定义输出:能输出用户指定的前n多的单词与其数量

    (1).-i 参数设定读入的文件路径

    格式如下

    wordCount.exe -i [file]

    一个例子如:

    wordCount.exe -i input.txt

    (2).-m 参数设定统计的词组长度

    格式如下

    wordCount.exe -m [number]

    词组定义:m个由分隔符隔开的单词组成一个词组
    -m参数与数字配套使用,用于设置词组长度
    命令行中使用-m参数,例:

    wordCount.exe -m 3 -i input.txt
    /*
     *要求程序统计input.txt中长度为3的词组,最终输出
     *例:input文件中内容为"Monday Tuesday Wednesday Thursday"
     *则输出如下
     */
    characters: 33
    words: 4
    lines: 1
    Monday Tuesday Wednesday: 1
    Tuesday Wednesday Thursday: 1

    (3)-n参数设定输出的单词数量

    格式如下

    wordCount.exe -n [number]

    -n参数与数字搭配使用,用于限制最终输出的单词的个数
    表示输出最多的前[number]个单词
    命令行中使用-n参数,例:

    wordCount.exe -n 1 -i input.txt
    /*
     *程序会输出文件中出现次数最多的那个单词
     */

    (4) -o 参数设定生成文件的存储路径

    格式如下

    wordCount.exe -o output.txt

    则将统计信息输出到文件 output.txt中。

    (5) 多参数的混合使用

    在实际测试时,-i 与 -o 参数一定会出现(但文件路径不一定正确),但-n或-m 参数可能不出现,参数之间的顺序并不固定,一个完整例子如下

    wordCount.exe -i input.txt -m 5 -n 3 -o output.txt
     

    第四步、附加功能

    附加需求:用户交互界面绘制(10')

    现在已经有了一个词频统计程序的命令行版本,如果想让大家都能实际使用它,还需要一个简单的界面。请为你们的程序做一个GUI界面,并附上一个简单的使用说明。界面需正确实现下述功能,会按点给分:

    1. 支持两种导入单词文本的方式:①导入单词文本文件,②直接在界面上输入单词并提交(3')
    2. 提供可供用户交互的按钮和,实现-i -m -n -o 这四个参数的功能,对于异常情况需要给予用户提示(3')
    3. 将结果直接输出到界面上,并提供“导出”按钮,将结果保存到用户指定的位置(3')

    以上功能全部正确完成,可以获得10分满分。

    【注意】选择完成本附加题目的同学,需要将GUI与单词计算模块作为两个工程开发,后者可以作为依赖库为前者提供调用接口,但不可以把两个工程直接混在一起。 GUI相关的部分也需要提供新的可执行文件,放在根目录的GUIBIN文件夹下。

     

    第五步、错误处理并设计单元测试

    现在我们封装了接口,并增加了新功能,现在我们要对我们的代码进行正确性验证。
    另一方面我们都知道健壮性对于软件来说是非常必要的,请各位使用单元测试对项目进行测试,并使用插件查看测试分支覆盖率等指标;另外,请准备至少10个测试用例确保你的程序能够正确处理各种情况,并且不会崩溃。
    对待错误的输入,能够尽可能精确报错(就像编译器一样)。
    你可以有“容错性”的出错设计,但必须输出必要的提示或说明。

    第六步、效能分析

    现在我们已经有了一个基础的词频统计软件,如果它通过了足够多的单元测试,那它可能也已经是一个比较完善的词频统计软件了。但是一个软件光正确了还不够,还需要有一定的性能。
    那么,如何让软件又快又好地执行呢?那就需要我们找到执行消耗时间最久的模块,然后不断地优化改进它。那么,如何知道哪些语句是软件的时间瓶颈呢,这就需要用到效能分析。

    以下链接中的Part6部分有效能分析的介绍

    https://www.cnblogs.com/ChildishChange/p/10398212.html

    4.评分细则

    博客评分规则(总分100)

    (1)          在文章开头给出你们Fork仓库的Github项目地址。(5')

    (2)          在开始实现程序之前,在下述PSP表格记录下你估计将在程序的各个模块的开发上耗费的时间。(5')

    (3)          计算模块接口的设计与实现过程。 设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。并讲讲你的设计是如何体现“Design by Contract”、“Information Hiding”、 “Interface Design”、 “Loose Coupling”等原则的。(25')

    (4)          代码复审过程。代码互审情况、发现的问题等。(10‘)

    (5)          计算模块接口部分的性能改进。 记录在改进计算模块性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2017/JProfiler的性能分析工具自动生成),并展示你程序中消耗最大的函数。(10')

    (6)          计算模块部分单元测试展示。 展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。(15')

    (7)          计算模块部分异常处理说明。 在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。(10')

    (8)          描述结对的过程,提供非摆拍的两人在讨论的结对照片。(5')

    (9)          在你实现完程序之后,在附录提供的PSP表格记录下你在程序的各个模块上实际花费的时间。(5')

    (10)       附加功能(10') 

    5.附录

    (1)PSP表格

    PSP2.1

    Personal Software Process Stages

    预估耗时(分钟)

    实际耗时(分钟)

    Planning

    计划

    · Estimate

    · 估计这个任务需要多少时间

    Development

    开发

    · Analysis

    · 需求分析 (包括学习新技术)

    · Design Spec

    · 生成设计文档

    · Design Review

    · 设计复审 (和同事审核设计文档)

    · Coding Standard

    · 代码规范 (为目前的开发制定合适的规范)

    · Design

    · 具体设计

    · Coding

    · 具体编码

    · Code Review

    · 代码复审

    · Test

    · 测试(自我测试,修改代码,提交修改)

    Reporting

    报告

    · Test Report

    · 测试报告

    · Size Measurement

    · 计算工作量

    · Postmortem & Process Improvement Plan

    · 事后总结, 并提出过程改进计划

    合计

    PSP是卡耐基梅隆大学(CMU)的专家们针对软件工程师所提出的一套模型:Personal Software Process (PSP, 个人开发流程,或称个体软件过程)。

    一个功能完备的程序不是一蹴而就的。通过将词频统计的需求划分为4个部分,可将一个大任务划分为可操作的小任务,同时最好按照任务难度或紧急程度指定各个任务的完成次序。因此,在动手开发之前,要先估计将在程序各模块开发所需耗费的时间,以及完成整个项目所需的时间,将这个[估计值]记录下来,写成PSP 的形式。
    PSP的目的是:记录工程师如何实现需求的效率,和我们使用项目管理工具(例如微软的Project Professional,或者禅道等)进行项目进度规划类似。
    有关PSP的更多内容,请自行阅读邹欣老师的博客:
    http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html

    (2) Github

    请阅读邹欣老师的博客:https://www.cnblogs.com/xinz/p/5044037.html  源代码管理,了解源代码管理的10个实践问题。
    本次作业要求使用Github进行源代码管理,代码有进展即签入Github。签入记录不合理的项目会被助教抽查询问项目细节。
    对代码签入的具体要求如下:根据需求划分功能后,每做完一个功能,编译成功后,应至少commit一次。本例中,至少应区分基本功能和扩展功能,即分别针对基本功能、扩展功能,编译成功后,总共至少应commit两次。具体的功能划分,请自行定义,并在撰写博客时体现出来,遵循自己对需求的功能划分来提交代码即可。
    对Commit不是很熟悉的话,请阅读阮一峰的博客:Commit message 和 Change log 编写指南,了解更多细节。

    (3)单元测试

    请根据自己以往积累的测试经验,在编码完成之后,提交产品之前,设计测试用例,并编写单元测试,对自己的项目进行测试。
    首先,至少应采用白盒测试用例设计方法来设计测试用例,其他测试方法不限。其次,要设计至少10个测试用例,确保你的程序能够正确处理各种情况。最后,结合测试评估的要求,对自己的测试设计进行评价,这些测试用例能满足该程序测试的要求吗?
    另一个重要的措施是要把单元测试自动化,这样每个人都能很容易地运行它,并且可以使单元测试每天都运行。每个人都可以随时在自己的机器上运行。团队一般是在每日构建中运行单元测试的,这样每个单元测试的错误就能及时被发现并得到修改。
    推荐阅读邹欣老师关于单元测试和回归测试的博客:
    http://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html

    6.提醒

    (1)代码不要出现抄袭或者直接拷贝的现象,一旦发现作业将没有成绩。

    (2)确保代码能够运行通过,代码不能通过,则博客成绩最多给60分。

    (3)博客要体现出自己的思想,每个人遇到的问题和解决方法以及感获得的感受都应是不一样的,博客出现抄袭或者拷贝现象,一旦发现作业将没有成绩。

    7.参考

    本作业参考北京航空航天大学发布的作业:结对编程 - 词频统计,在此表示感谢!

  • 相关阅读:
    历史博文汇总
    Golang快速入门:从菜鸟到大佬
    网络1911、1912 DS第4次作业--批改总结
    [机器学习实战-Logistic回归]使用Logistic回归预测各种实例
    [机器学习实战-kNN算法]约会网站问题和手写数字系统实例
    SQL学习笔记(一)之基础语句
    Python学习笔记(九)之面向对象编程(下)
    Python学习笔记(八)之面向对象编程(上)
    Python学习笔记(七)之Python模块
    Python学习笔记(六)之函数式编程
  • 原文地址:https://www.cnblogs.com/harry240/p/11524113.html
Copyright © 2011-2022 走看看