软件工程1916|W (福州大学)

  1. 班级首页
  2. 作业列表
  3. 详情

结对第二次—文献摘要热词统计及进阶需求 [已截止]


请大家在作业开头添加格式描述:

这个作业属于哪个课程 <课程的链接>
这个作业要求在哪里 <作业要求的链接>
结对学号 <写上两个结对同学的学号>
这个作业的目标  <写上具体方面>
作业正文 .... 注意代码要按格式上传
其他参考文献 ...

本次任务

本次作业分为两部分:
一、基本需求:实现一个能够对文本文件中的单词的词频进行统计的控制台程序。
二、进阶需求:在基本需求实现的基础上,编码实现顶会热词统计器。

特别说明:只要实现基本功能就有个基本分数,但是实现进阶的得到更多的分数。

一、WordCount需求

(一)WordCount基本需求

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

第一步、实现基本功能
输入文件名以命令行参数传入。例如我们在命令行窗口(cmd)中输入:

//C语言类
wordCount.exe input.txt

//Java语言
java wordCount input.txt

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

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

characters: number
words: number
lines: number
<word1>: number
<word2>: number
...

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

同时我们也看到,不同的代码解决不同层面的问题:

  1. 有些是计算数据的(例如统计单词)
  2. 有些是控制输入的(例如scanf,cin,图形界面的输入字段)
  3. 有些是数据可视化的(例如printf,cout,println,DrawText)
  4. 有些则更为特殊,是架构相关的(例如main函数,并不是所有的程序都需要某个特定格式的main)

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

  1. 统计字符数
  2. 统计单词数
  3. 统计最多的10个单词及其词频

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

  1. 命令行测试程序使用
  2. 在单元测试框架下使用
  3. 与数据可视化部分结合使用

把计算核心在单元测试框架中做过完备的测试后,我们就可以在算法层级保证了这个模块的正确性。
但我们知道软件并非只有计算核心,实际的软件是交付给最终用户的软件,除了计算核心外,还需要有一定的界面和必要的辅助功能。
这个Core模块和使用它的其他模块之间则要通过一定的API来交流。

API应该怎么设计呢?
为了方便起见,我们可以从下面的最简单的接口开始(仅举例,你的代码里可能没有这个函数):

int countChar(File *file)

这个函数表示输出一个文件指针,返回这个文件的字符数。
假设我们用Core封装了这个接口,那么我们的测试程序可以是这样:

File *in = fopen("input.txt","r");
int count = 100;
Assert(countChar(in) == count);

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

(二)WordCount进阶需求

新增功能,并在命令行程序中支持下述命令行参数。说明:字符总数统计、单词总数统计、有效行统计要求与个人项目相同

1. 使用工具爬取论文信息

  • CVPR2018官网爬取今年的论文列表,输出到result.txt(一定叫这个名字),内容包含论文题目、摘要,格式如下:

    • 为爬取的论文从0开始编号,编号单独一行
    • 两篇论文间以2个空行分隔
    • 在每行开头插入“Title: ”、“Abstract: ”(英文冒号,后有一个空格)说明接下来的内容是论文题目,或者论文摘要
    • 后续所有字符、单词、有效行、词频统计中,论文编号及其紧跟着的换行符、分隔论文的两个换行符、“Title: ”、“Abstract: ”(英文冒号,后有一个空格)均不纳入考虑范围

可参考样例如下:

  • 请在博客中注明你所使用的爬虫工具,并说明如何使用
    • 如果是使用C++或Java实现的,在博客中简单解释你的思路,会有额外加分

2.自定义输入输出文件

  • -i 参数设定读入文件的存储路径,-o 参数设定生成文件的存储路径
    • 格式如下:

WordCount.exe -i [file] -o [file]

一个例子如:

WordCount.exe -i input.txt -o output.txt

/*

*从input.txt读取需要统计的文本,将统计结果输出到output.txt

*/

3. 加入权重的词频统计

  • 属于Title的单词权重为10,属于Abstract 单词权重为1
    • 在上文图片样例中,embodied 的频率为 1x10+2x1=12。(在题目中出现1次,在摘要中出现2次,其中1次由于图片大小未能显示)
  • 进行单词统计时依旧正常累加
  • -w 参数设定是否采用不同权重计数
    • -w 参数与数字 0|1 搭配使用,用于表示是否采用不同权重:0 表示属于 Title、Abstract 的单词权重相同均为 1 ;1 表示属于 Title 的单词权重为10,属于Abstract 单词权重为1。格式如下:

WordCount.exe -w [0|1]

一个例子如:

WordCount.exe -w 1

/*

*程序会输出input.txt中采用不同权重统计出的词频前10的单词

*/

4. 新增词组词频统计功能

  • 统计文件夹中指定长度的词组的词频

    • m 个由分隔符隔开的单词组成一个词组,词组只存在于同一个字段中,即不能跨越 Title、Abstract - 组成词组
    • 使用词组词频统计功能时,不再统计单词词频,而是统计词组词频,但不影响单词总数统计
    • 最终只输出频率最高的10个词组,频率相同的词组,优先输出字典序靠前的词组
  • -m 参数设定统计的词组长度

    • -m 参数与数字配套使用,用于设置词组长度,格式如下:

WordCount.exe -m [number]

一个例子如:

WordCount.exe -m 3

/*

*要求程序统计长度为3的词组

*/

例:输入文件中内容为:

0

Title: Monday Tuesday Wednesday Thursday

Abstract: Friday

则输出如下:

characters: 40

words: 5

lines: 2

<monday tuesday wednesday>: 1

<tuesday wednesday thursday>: 1

5. 自定义词频统计输出

  • 用户指定输出前 n 多的单词(词组)与其频数

  • -n 参数设定输出的单词数量

  • -n 参数与数字搭配使用,用于限制最终输出的单词(词组)的个数,表示输出频数最多的前 [number] 个单词(词组),0 ≤ [number] ≤ 100格式如下:

WordCount.exe -n [number]

一个例子如:

WordCount.exe -n 1

/*

*输出文件中出现次数最多的那个单词

*/

6. 多参数的混合使用
实际测试时,在一句命令行语句中

  • -i 、-o 、-w 参数一定会出现

  • -m、-n 参数可能都不出现,可能只出现一个,也可能都出现

    • 未出现 -m 参数时,不启用词组词频统计功能,默认对单词进行词频统计

    • 未出现 -n 参数时,不启用自定义词频统计输出功能,默认输出10个

  • 参数之间的顺序并不固定

    • 一个完整例子如下:

WordCount.exe -i input.txt -m 3 -n 3 -w 1 -o output.txt

/*

*统计input.txt文件中的字符数、单词数、有效行数、出现次数排在前3的3个单词长的词组,并采用权重累>计频数,最终统计结果输出到output.txt

*/

例:输入文件中内容为:

0

Title: Monday Tuesday Wednesday Thursday

Abstract: Monday Tuesday Wednesday Thursday Friday

则输出如下:

characters: 74

words: 9

lines: 2

<monday tuesday wednesday>: 11

<tuesday wednesday thursday>: 11

<wednesday thursday friday>: 1

7. 附加题(20')
本部分不参与自动化测试,如有完成,需在博客中详细描述,并在博客中附件(.exe及.txt)为证。附加功能的加入不能影响上述基础功能的测试,分数取决于创意和所展示的完成度,创意没有天花板,这里不提出任何限制,尽你们所能去完成。

要求:结合结对原型设计,发挥个人的奇思妙想,对论文列表进行更多的挖掘并进行数据分析,为你们举几个例子:

  • 从网站综合爬取论文的除题目、摘要外其他信息
    • 如:论文类型、作者、作者单位等等
  • 分析论文作者的所属地, 哪些国家、哪些高校发表的论文比较多

  • 分析论文列表中各位作者之间的关系,论文A的第一作者可能同时是论文B的第二作者,不同论文多位作者之间可能存在着联系

  • 对数据的图形可视化做出一些努力,比如对上一条功能可以形成关系图谱

二、编码要求

  1. Fork github 项目 https://github.com/EventideX/PairProject1-C.githttps://github.com/EventideX/PairProject1-Java.git到自己的仓库,在Github仓库中新建一个 队友1学号&队友2学号为名的文件夹,完成WordCount基本需求的实现,正确发起一个Pull Request。
    2.Fork github项目 https://github.com/EventideX/PairProject2-C.githttps://github.com/EventideX/PairProject2-Java.git到自己的仓库,在Github仓库中新建一个“队友1学号&队友2学号”为名的文件夹,完成WordCount进阶需求的实现后正确发起一个Pull Request。
  2. 在开始实现程序之前,在PSP表格[附录1]记录下你估计在程序开发各个步骤上耗费的时间,在你实现程序之后,在PSP表格记录下你在程序的各个模块上实际花费的时间。
  3. 使用C++ 或者Java语言实现,C++请使用Visual Studio Community 2017进行开发,Java请使用,运行环境为64-bit Windows 10
  4. 提交的代码要求经过Code Quality Analysis工具的分析并消除所有的警告。
  5. 完成项目的首个版本之后,请使用性能分析工具Studio Profiling Tools来找出代码中的性能瓶颈并进行改进。
  6. 使用Github[附录2]来管理源代码和测试用例,代码有进展即签入Github。签入记录不合理的项目会被助教抽查询问项目细节。
  7. 使用单元测试[附录3]对项目进行测试,并使用插件查看测试分支覆盖率等指标;并写出至少10个测试用例确保你的程序能够正确处理各种情况。
  8. 在完成项目后,请按 github介绍正确发起一个Pull Request,并确保基本需求代码最终成功签入到 https://github.com/EventideX/PairProject1-C.githttps://github.com/EventideX/PairProject1-Java.git 中;进阶需求代码最终成功签入到https://github.com/EventideX/PairProject2-C.githttps://github.com/EventideX/PairProject2-Java.git中。
  9. 两人制定需要共同遵守的代码规范,并在博客中说明各自负责的部分。

三、博客撰写要求及博客评分规则

1.在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址,【1'】并贴出Github的代码签入记录【1'】
2.给出具体分工【1'】

  1. 给出PSP表格【2'】
  2. 解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。【5'】
  3. 设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?代码组织与内部实现设计(类图)【5'】说明算法的关键与关键实现部分流程图【5'】
  4. 记录在改进程序性能上所花费的时间,描述你改进的思路
    描述你改进的思路【8'】展示性能分析图和程序中消耗最大的函数【2'】
  5. 代码说明。展示出项目关键代码,并解释思路与注释说明。【8'】
  6. 展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路【7'】
  7. 结合在构建之法中学习到的相关内容,撰写遇到的代码模块异常或结对困难及解决方法。【3'】评价你的队友:值得学习的地方和需求改进的地方【2'】
  8. 附加题设计与展示:设计的创意独到之处、实现思路、实现成果展示【20'】

四、测试须知

助教在测试时,将运行自动测试程序编译源文件并运行,进行批量测试,因此请保证项目的组织目录符合要求.

基本需求的项目组织要求

用Java语言的项目有以下两点要求:

  1. 队友1学号&队友2学号为名的文件夹中】的目录下必须有src文件夹
  2. 在src目录下必须有名为Main.java文件,且Main.java中包含 public static void main(String[] args) 方法
    一个Java项目的示例组织目录如下所示:

221602222&221602203 (文件夹名字为结对同学的学号用&隔开)
|- src
 |- Main.java(主程序,可以从命令行接收参数)
 |- lib.java(包含其它自定义函数,可以有多个,对名字不做要求)

对于使用C++ 语言的项目有以下两点要求:

队友1学号&队友2学号的文件夹中】的目录下必须有src文件夹,在src文件夹中是可在VS2017下编译运行的解决方案,解决方案的名字必须为 WordCount,一个C++工程示例组织目录如下所示:

221602111&221602103 (文件夹名字为结对同学的学号用&隔开)

|- src
 |- WordCount.sln
 |- WordCount
   |- stdafx.cpp
   |- stdafx.h
   |- WordCount.cpp
   |- WordCount.vcxproj

进阶需求的项目组织要求:

一个Java项目的示例组织目录如下所示:

221602222&221602203 (文件夹名字为结对同学的学号用&隔开)

|- src

  |- Main.java(主程序,可以从命令行接收参数)

  |- lib.java(包含其它自定义函数,可以有多个,对名字不做要求)

  |- Main.class(编译生成的可运行程序)

  |- lib.class(编译生成的可运行程序)

|- cvpr

  |- result.txt(爬虫结果)

  |- Main.java(爬虫程序,可以爬取CVPR2018论文列表)

一个C++工程示例组织目录如下所示:

221602222&221602203 (文件夹名字为结对同学的学号用&隔开)

|- src

   |- WordCount.sln

   |- WordCount

   |- stdafx.cpp

   |- stdafx.h
  
   |- WordCount.cpp
  
   |- WordCount.vcxproj

|- cvpr

   |- result.txt(爬虫结果)

   |- Crawler.cpp(爬虫程序,可以爬取CVPR2018论文列表)

规范说明

  • 助教在测试时,将自动按照指定目录搜索文件,使用指定编译环境编译源代码,并利用命令行进行批量测试,请务必遵照上述组织目录

    错误处理

    本次自动测试会加入各种各样出错情况的测试,要求开发者程序不能崩溃,并且能够尽可能精确报错。你可以有“容错性”的出错设计,但必须输出必要的提示或说明。

    关于在Github的上传

    • 不要上传整个项目工程文件,很大
    • 不要上传单元测试工程文件,测试详情请在博客中写明
    • 不要把作业上传在结对文件夹以外的地方,可能导致冲突
  • 助教会在作业结束后统一处理 pr
  • 进阶需求的测试数据将采用CVPR2018会议论文的实际数据
    • 一共10个测试用例,每个用例限时60s
    • 每通过一个用例得分+20,其中字符统计正确+1,单词统计正确+1,有效行统计正确+1,词频统计正确+15,单个用例执行时间在10s内+2(可能适应总体情况调整)
  • 进阶需求的用例较大,请保证你们的程序不会崩溃,可使用爬虫的结果检验程序性能

五、程序评分规则

  • 正确性:基本需求正确完成【30'】进阶需求正确完成【30'】
  • 性能【20'】
    -说明: 当基本需求程序的正确性评分大于25分时才可以参与基本需求性能评分环节;进阶需求程序的正确性评分大于25分时才可以参与进阶需求性能评分环节,所以请各位同学务必保证自己程序的正确性。
  • 性能评分将采取档级评分制度,助教将根据同学们的程序跑同一数据耗费的时间长度将程序分为若干档,每一档的同学得到的分数为 10/档级数

注意事项:

  • 按时间完成并提交——正常评分
  • 晚交一周以内——0分
  • 晚交一周以上或不交——倒扣本次作业分数
  • 抄袭——倒扣2倍本次作业分数【严禁代码与博客等一切形式的抄袭!】

疑惑解疑
若有对题意不清或者有不理解的地方,可在该博客下方留言,或者在微信群中直接提问。

附录

1.PSP表格

PSP是卡耐基梅隆大学(CMU)的专家们针对软件工程师所提出的一套模型:Personal Software Process (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 • 事后总结, 并提出过程改进计划
合计

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

2.Github

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

3.单元测试

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


学号 成员名 提交作业标题 提交日期 分数
提交: 71 人,未提交: 14 人
未提交名单: haziza    哈库呐玛塔塔611    花落空白忆丶    为了交项目干杯    修!咻咻!    北风团子    NSJN    火鸡堂    待就业六人组    Echo团队    云打印    CodingMaster    Htxue    SkyReach