软件工程第二次作业--文件读取

助教-孔志豪 社区管理员 2024-02-17 22:01:15

软件工程实践第二次作业——个人实战

恭喜你已经完成了软工实践的第一次作业,并将逐步迈进到第二次作业的能力提升中。本次作业将聚焦于世界游泳锦标赛跳水赛事项目,期待各位同学大展身手哦!
为了不遗漏作业内容,这里有一份checklist方便你快速查阅

  • 在文章开头给出新建的Gitcode项目地址
  • 详细阅读作业要求
  • 完成代码编写并进行测试
  • 撰写博客
    • 描述解题思路
    • 设计实现过程
    • 关键代码展示
    • PSP表格
    • 核对作业评分标准
  • 在deadline之前,在社区中提交作业本次作业的截止日期为3月3日

0. 任务

完成对世界游泳锦标赛跳水项目相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序

1. 编码要求

  1. 根据你选择的编程语言,从下面两个项目中Fork一个到自己的仓库,然后在根目录中新建一个学号为名的文件夹。(将自己的文件全部保存在以自己学号命名的文件夹下!!!)

    https://gitcode.net/xxdhd1/project-c
    https://gitcode.net/xxdhd1/project-java
    
  2. 复制example(在project-c项目仓库中)下的目录结构到你新建的目录下;不要修改example文件夹和根目录下的README

  3. 语言支持:

    1. Java:Java8,推荐使用Java开发
    2. c/c++:gcc/g++ 6.3
    3. 换行使用'\n',编码统一使用UTF-8
  4. 在开始实现程序之前,在PSP表格[附录1]记录下你估计在程序开发各个步骤上耗费的时间,在你实现程序之后,在PSP表格记录下你在程序的各个模块上实际花费的时间。

  5. 使用GitCode[附录2]来管理源代码,代码有进展即签入GitCode,至少进行10次以上的commit修改。签入记录不合理的项目会被助教抽查询问项目细节。

  6. 请制定自己的代码规范并撰写成markdown文件,随代码一起上传至GitCode仓库中。可以参照《码出高效_阿里巴巴Java开发手册》/《腾讯c++代码规范》等主流代码规范来制定你自己的编程规范。编码要求项目代码的风格要符合你制定的代码规范。

  7. 除了目录组织说明提及的文件,其它自己产生的文件都应该在.gitignore忽略,如编译器生成的项目文件、输出文件、class、jar包、exe等,确保不会提交到GitCode上,参考 [附录3]。

  8. 进行性能分析和改进

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

  10. 在完成项目后,deadline之前,请正确发起一个Pull Requet [附录2],并确保自己的代码最终成功签入。(如果成功签入会在原始项目主页看到自己学号为名的文件夹)

2. 博客撰写要求

  1. 在文章开头给出Gitcode项目地址
  2. 给出PSP表格
  3. 解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。
  4. 设计与实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(展示出项目关键代码),并解释思路,以及独到之处。
  5. 程序性能改进。记录在改进程序性能上所花费的时间,描述你改进的思路。
  6. 单元测试展示。展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。将单元测试得到的测试覆盖率截图,发表在博客中;描述应该如何优化覆盖率?
  7. 结合在构建之法中学习到的相关内容,撰写解决项目的心路历程与收获

3. 需求

实现一个命令行程序,不妨称之为DWASearch
本次作业所需数据均爬取自世界游泳锦标赛官网的跳水项目比赛结果参赛选手信息【该爬取行为仅用于课程教学】
数据收集部分可以参考往届优秀作业[参考链接]
如果对收集数据感到困难,助教这里也提供了相关的数据,供同学们使用,数据保存在仓库中example/data文件夹内。

3.1 实现基本功能

假设有一个软件可以输出2024世界游泳锦标赛跳水项目的选手信息和比赛结果。
输入指令和输出文件以命令行参数传入。例如我们在命令行窗口(cmd)中输入:

//C语言类
DWASearch.exe input.txt output.txt
 
//Java语言
Java -jar DWASearch.jar input.txt output.txt

功能1:输出所有选手信息

当input.txt的内容为

players

则会输出参与世界游泳锦标赛跳水项目的所有选手信息output.txt,输出格式如下:

  1. 其中Full Name对应选手全名,Gender为选手性别, Country为国籍。
  2. 换行使用'\n',编码统一使用UTF-8。
  3. 顺序以国籍为首要关键字升序、选手的名(Last Name)为次要关键字升序排序(若爬取的数据已经排序完成则仅需要依次提取需要的信息,不必编写排序过程的代码)。
  4. 每输出一个选手的相关信息后,以5个“-”单独成行作为分割线,最后一个选手信息输出后仍要输出一行分割线。
  5. 输出的内容中除选手名称和选手国籍可能存在空格,其他信息不得增加多于的空格或者其他符号。

输出格式:

Full Name:string
Gender:string
Country:string 
-----
...
-----
Full Name:string
Gender:string
Country:string 
-----

输出样例:

Full Name:HART Alexander
Gender:Male
Country:Austria
-----
Full Name:LOTFI Dariush
Gender:Male
Country:Austria
-----
...
-----
Full Name:DICK Elaena
Gender:Female
Country:Canada
-----

功能2:输出决赛每个运动项目结果

当input.txt的内容为

result women 1m springboard

则会输出女子1m跳板的决赛结果到output.txt,输出格式如下:

  1. Full Name对应选手姓名。
  2. Rank为排名。格式如'1'
  3. Score表示决赛中该选手的成绩。格式如'score1 + score2 + score3 + ··· + score7 = totalPoint'

输出格式:

Full Name:string
Rank:string
Score:string
-----
...
-----
Full Name:string
Rank:string
Score:string
-----

输出样例:

Full Name:MULLER Jette
Rank:1
Score:51.60 + 52.00 + 51.75 + 46.80 + 46.80 = 248.95
-----
Full Name:ROLLINSON Amy
Rank:2
Score:46.00 + 42.90 + 50.70 + 54.00 + 46.80 = 240.40
-----
...
-----
Full Name:SANTIAGO Dominique
Rank:12
Score:42.00 + 18.20 + 35.70 + 34.50 + 32.55 = 162.95
-----

附加功能:输出详细结果
当input.txt的内容为

result women 10m platform detail

则会输出世界游泳锦标赛跳水项目女子10m跳台的所有比赛结果到output.txt,输出格式如下:

  1. Full Name对应选手姓名。
  2. Rank为排名。格式如'1 | 2 | 3'表示初赛排名为1,半决赛排名为2,决赛排名为3。部分比赛若无半决赛或初赛又或者选手未参加半决赛或决赛的则用'*'占位表示,如'* | * | 1'
  3. Preliminary Score表示初赛中该选手的成绩。格式如'score1 + score2 + score3 + ··· + score7 = totalPoint'。若无初赛则用'*'表示。
  4. Semifinal Score表示半决赛中该选手的成绩。格式如'score1 + score2 + score3 + ··· + score7 = totalPoint'。若无半决赛或者选手未参加则用'*'表示。
  5. Final Score表示决赛中该选手的成绩。格式如'score1 + score2 + score3 + ··· + score7 = totalPoint'。若选手未参加则用'*'表示。
  6. 输出顺序按照选手第一次比赛的排名顺序输出。
  7. 注意空格出现的位置,不能有多于的空格,否则会被判定为格式错误。
  8. [补充] 如果遇到双人项目,选手姓名格式命名为'A & B'按照选手名(Last Name)从小到大排序,例如'JACHIM Filip & LUKASZEWICZ Robert'

输出格式:

Full Name:string
Rank:string
Preliminary Score:string
Semifinal Score:string
Final Score:string
-----
...
-----
Full Name:string
Rank:string
Preliminary Score:string
Semifinal Score:string
Final Score:string
-----

输出样例:

Full Name:FUNG Katelyn
Rank:1 | 4 | 2
Preliminary Score:60.20 + 56.00 + 57.60 + 54.00 + 70.40 = 298.20
Semifinal Score:46.20 + 30.80 + 68.80 + 61.50 + 67.20 = 274.50
Final Score:58.80 + 54.60 + 57.60 + 54.00 + 72.00 = 297.00
-----
...
-----
Full Name:SANTIAGO Dominique
Rank:14 | 11 | 11
Preliminary Score:39.20 + 21.00 + 41.85 + 31.20 + 13.05 = 146.30
Semifinal Score:42.00 + 22.50 + 17.55 + 42.90 + 39.15 = 164.10
Final Score:42.00 + 28.50 + 20.25 + 41.60 + 44.95 = 177.30
-----

补充说明:
对于input.txt,有可能会出现多行输入的样例,例如:

players
result women 1m springboard
result women 1m springboard
players

此时的输出文件output.txt中的内容为:

Full Name:HART Alexander
Gender:Male
Country:Austria 
-----
Full Name:LOTFI Dariush
Gender:Male
Country:Austria
-----
...
-----
Full Name:MULLER Jette
Rank:1
Score:51.60 + 52.00 + 51.75 + 46.80 + 46.80 = 248.95
-----
Full Name:ROLLINSON Amy
Rank:2
Score:46.00 + 42.90 + 50.70 + 54.00 + 46.80 = 240.40
-----
...
-----
Full Name:MULLER Jette
Rank:1
Score:51.60 + 52.00 + 51.75 + 46.80 + 46.80 = 248.95
-----
Full Name:ROLLINSON Amy
Rank:2
Score:46.00 + 42.90 + 50.70 + 54.00 + 46.80 = 240.40
-----
...
-----
Full Name:HART Alexander
Gender:Male
Country:Austria 
-----
Full Name:LOTFI Dariush
Gender:Male
Country:Austria
-----
...
-----
Full Name:MYALIN Igor
Gender:Male
Country:Uzbekistan
-----

其中,每个指令的输出紧贴上一个指令的输出,无需空行

指令区分大小写,指令中所有的英文字母都采用小写的形式
假如输入无法处理的指令,例如:

  1. 无法识别的指令,则输出Error
  2. result后的比赛项目名称应为如下这些名称之一,如果不正确,则输出N/A
    women 1m springboard
    women 3m springboard
    women 10m platform
    women 3m synchronised
    women 10m synchronised
    men 1m springboard
    men 3m springboard
    men 10m platform
    men 3m synchronised
    men 10m synchronised
    
  3. 在比赛项目名称后只能加上'detail'字符,如果字符不正确,则输出N/A

input.txt样例:

player
Players
resultwomen 1m springboard
result women 10m springboard
result sss
result detail
result women 1m springboard details
result men 10m     synchronised
players

output.txt输出:

Error
-----
Error
-----
Error
-----
N/A
-----
N/A
-----
N/A
-----
N/A
-----
N/A
-----
Full Name:HART Alexander
Gender:Male
Country:Austria 
-----
Full Name:LOTFI Dariush
Gender:Male
Country:Austria
-----
...
-----
Full Name:MYALIN Igor
Gender:Male
Country:Uzbekistan
-----

3.2 接口封装

如果现在我们要把这个功能放到不同的环境中去(例如,命令行,Windows图形界面程序,网页程序,手机App),就会碰到困难:代码散落在各个函数中,很难剥离出来作为一个独立的模块运行以满足不同的需求。
这些代码的种类不同,混杂在一起对于后期的维护扩展很不友好,所以它们的组织结构就需要精心的整理和优化。

我们希望把基本功能里的:

  1. 输出所有选手信息
  2. 输出每个比赛项目的结果

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

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

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

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

int countChar(File *file)

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

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

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

3.3 单元测试和性能分析

请根据自己以往积累的测试经验,在编码完成之后,提交产品之前,设计测试用例,并编写单元测试,对自己的项目进行测试。
首先,至少应采用白盒测试用例设计方法来设计测试用例,其他测试方法不限。其次,要设计至少10个测试用例,确保你的程序能够正确处理各种情况。最后,结合测试评估的要求,对自己的测试设计进行评价,这些测试用例能满足该程序测试的要求吗?

另一个重要的措施是要把单元测试自动化,这样每个人都能很容易地运行它,并且可以使单元测试每天都运行。每个人都可以随时在自己的机器上运行。团队一般是在每日构建中运行单元测试的,这样每个单元测试的错误就能及时被发现并得到修改。

  • 请阅读邹欣老师的博客:单元测试和回归测试,编写程序的单元测试
  • c++可以使用vs2017。对于博客任务中的单元测试、性能分析(Studio Profiling Tools),vs2017有相应的功能。
  • java可以使用idea。也可以自行查找使用其他工具。

4. 测试须知

4.1 组织目录

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

4.2 Java

对于使用Java语言的项目有以下要求:

  1. 【以学号为名的文件夹中】的目录下必须有src文件夹
  2. 在src目录下必须有名为DWASearch.java文件,且DWASearch.java中包含 public static void main(String[] args) 方法
  3. 请将Java代码打包成jar
  4. 除此之外的文件都不需要提交到Gitcode仓库;一个Java项目的示例组织目录如下所示:
xxxxxxxxx (文件夹名字为学号)
|- src
 |- DWASearch.java(主程序,可以从命令行接收参数;确保文件名一致、区分大小写)
 |- Lib.java(包含其它自定义函数,可以有多个,对名字不做要求)
 |- data(文件夹,存放程序的数据)
|- DWASearch.jar
|- README.md
 描述你的项目,包括如何运行、功能简介、作业链接、博客链接等
|- codestyle.md
 描述你之前定的代码风格

4.3 C++

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

  1. 【以学号为名的文件夹中】的目录下必须有src文件夹
  2. 在src目录下必须有名为DWASearch.cpp文件,且DWASearch.cpp的main函数可以接收命令行参数(如int main(int argv, char** argc)
  3. 请将代码编译为exe
  4. 除此之外的文件都不需要提交到Gitcode仓库;一个C++项目的示例组织目录如下所示:
xxxxxxxxx (文件夹名字为学号)
|- src
  |- DWASearch.cpp(主程序,可以从命令行接收参数;确保文件名一致、区分大小写)
  |- Lib.cpp(包含其它自定义函数,可以有多个,对名字不做要求)
  |- Lib.h(包含其它自定义函数,可以有多个,对名字不做要求)
  |- data(文件夹,存放程序的数据)
|- DWASearch.exe
|- README.md
  描述你的项目,包括如何运行、功能简介、作业链接、博客链接等
|- codestyle.md
  描述你之前定的代码风格

4.4 错误处理

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

5、评分规则

5.1 博客评分规则(50')

  1. 在文章开头给出你们的Gitcode项目地址。(2')【覆盖课程目标1】
  2. 在开始实现程序之前,在附录提供的PSP表格中记录下你估计将在程序的各个模块中耗费的时间。(3')【覆盖课程目标2】
  3. 记录模块接口的设计与实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。(22')【覆盖课程目标2】
  4. 计算模块接口部分的性能改进。(8')【覆盖课程目标2】
  5. 计算模块部分单元测试展示。(8')【覆盖课程目标1】
  6. 计算模块部分异常处理说明。(4')【覆盖课程目标2】
  7. 在实现完程序后,在附录提供的PSP表格中记录下你在程序的各个模块中实际花费的时间。(3')【覆盖课程目标1】

5.2 程序评分规则(40')【覆盖课程目标3】

  1. 完成功能1(10')
  2. 完成功能2(15')
  3. 性能(10')
    当程序 (不包含附加功能) 的正确性评分大于等于25分时才可以参与性能评分环节,所以请各位同学务必保证自己程序的正确性。
    性能评分将采取档级评分制度,助教将根据同学们的程序跑同一数据耗费的时间长度将程序分为若干档,每一档的同学得到的分数为10/档级数
  4. 完成附加功能(5')

5.3 代码规范评分规则(10')【覆盖课程目标1】

  1. 囊括要求部分(2')
  2. 符合主流,制定合理,详细(3')
  3. 项目代码符合代码规范(5')

5.4 提交注意事项

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

5.5 疑惑解答

若有对题目不理解的地方,可在QQ群中直接提问。

6. 附录

1. PSP表格

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

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划
• Estimate• 估计这个任务需要多少时间
Development开发
• Analysis• 需求分析 (包括学习新技术)
• Design Spec• 生成设计文档
• Design Review• 设计复审
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)
• Design• 具体设计
• Coding• 具体编码
• Code Review• 代码复审
• Test• 测试(自我测试,修改代码,提交修改)
Reporting报告
• Test Repor• 测试报告
• Size Measurement• 计算工作量
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划
合计

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

2. Gitcode

请阅读邹欣老师的博客:源代码管理,了解源代码管理的10个实践问题。
本次作业要求使用GitCode进行源代码管理,代码有进展即签入GitCode。签入记录不合理的项目会被助教抽查询问项目细节。
对代码签入的具体要求如下:根据需求划分功能后,每做完一个功能,编译成功后,应至少commit一次。具体的功能划分,请自行定义,并在撰写博客时体现出来,遵循自己对需求的功能划分来提交代码即可。
如果对Gitcode的内容不熟悉,可以点击《git入门》进行学习

3. 单元测试

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

7. 格式与规则

7.1 为了方便其他学校的老师或者助教了解课程实况,请大家在作业开头添加作业的基本信息:(必做)

这个作业属于哪个课程<班级的链接>
这个作业要求在哪里<作业要求的链接>
这个作业的目标<写上具体方面>
其他参考文献...
  • markdown代码:
|这个作业属于哪个课程|<班级的链接>|
|--    |--    |
|这个作业要求在哪里|<作业要求的链接>|
|这个作业的目标|<写上具体方面>|
|其他参考文献|...    |

7.2 为了方便读者阅读以及助教评分,请大家在博客开头给出博文目录,作为内容的索引

  • 务必包含以下大标题: Gitcode项目地址、PSP表格、解题思路描述、接口设计和实现过程、关键代码展示、性能改进、单元测试、异常处理、心得体会(标题含义近似即可,你可以个性化自己的标题,如心路历程、性能测试)
  • 可以使用markdown的语法,根据标题设置自动生成目录:
[toc]
作业基本信息...
## Gitcode项目地址
## PSP表格
## 解题思路描述
### 问题1
### 问题2
...
## 接口设计和实现过程
...
## 关键代码展示
...
## 性能改进
...
## 单元测试
...
## 异常处理
...
## 心得体会
...
  • 也可以结合html生成目录
作业基本信息...
## 目录:
1. [Gitcode项目地址](#1)
2. [PSP表格](#2)
3. [解题思路描述](#3)
4. [接口设计和实现过程](#4)
5. [关键代码展示](#) 
6. [性能改进](#) 
7. [单元测试](#) 
8. [心得体会](#) 
## <span id="1">1. Gitcode项目地址</span>
### 问题1
### 问题2
### ...
## <span id="2">2. PSP表格</span>
...
## <span id="3">3. 解题思路描述</span>
...
## <span id="4">4. 接口设计和实现过程</span>
...
## <span id="5">5. 关键代码展示</span>
...
## <span id="6">6. 性能改进</span>
...
## <span id="7">7. 单元测试</span>
...
## <span id="8">8. 异常处理</span>
...
## <span id="9">9. 心得体会</span>
...
...全文
5635 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
0人已提交
完成率0%
暂无数据
回复
切换为时间正序
请发表友善的回复…
发表回复

116

社区成员

发帖
与我相关
我的任务
社区描述
FZU-SE
软件工程 高校
社区管理员
  • LinQF39
  • 助教-吴可仪
  • 一杯时间
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧