软工实践寒假作业(2/2)
寒假作业2
这个作业属于哪个课程 | 2020春|S班 (福州大学) |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 加强需求分析能力 |
作业正文 | 软工实践寒假作业(2/2) |
其他参考文献 | Markdown教程 |
1.GitHub 仓库地址
点击进入-> https://github.com/Allenaka/InfectStatistic-main
2.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 40 | 20 |
Estimate | 估计这个任务需要多少时间 | 60 | 50 |
Development | 开发 | 1680 | 1440 |
Analysis | 需求分析 (包括学习新技术) | 240 | 180 |
Design Spec | 生成设计文档 | 60 | 60 |
Design Review | 设计复审 | 60 | 45 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 20 |
Design | 具体设计 | 120 | 240 |
Coding | 具体编码 | 780 | 900 |
Code Review | 代码复审 | 120 | 100 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 180 |
Reporting | 报告 | 240 | 150 |
Test Repor | 测试报告 | 40 | 60 |
Size Measurement | 计算工作量 | 30 | 25 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 60 |
合计 | 3630 | 3530 |
3.解题思路
3.1 日志文件分析
日志中会出现的情况如下:
该日志中出现以下几种情况:
1、<省> 新增 感染患者 n人
2、<省> 新增 疑似患者 n人
3、<省1> 感染患者 流入 <省2> n人
4、<省1> 疑似患者 流入 <省2> n人
5、<省> 死亡 n人
6、<省> 治愈 n人
7、<省> 疑似患者 确诊感染 n人
8、<省> 排除 疑似患者 n人
由此可见,可以把每行读取的内容放入字符串,再用split()提取出关键词。
3.2 命令行分析
该程序通过从命令行输入命令运行的,例:
$ java InfectStatistic list -date 2020-01-22 -log D:/log/ -out D:/output.txt
InfectStatistic之后的参数都会作为main参数存放在args数组中。
java InfectStatistic表示执行主类InfectStatistic,list为命令,-date代表该命令附带的参数,-date后边跟着具体的参数值
list命令 支持以下命令行参数:
- -log 指定日志目录的位置,该项必会附带,请直接使用传入的路径,而不是自己设置路径
- -out 指定输出文件路径和文件名,该项必会附带,请直接使用传入的路径,而不是自己设置路径
- -date 指定日期,不设置则默认为所提供日志最新的一天。你需要确保你处理了指定日期以及之前的所有log文件
- -type 可选择[ip: infection patients 感染患者,sp: suspected patients 疑似患者,cure:治愈 ,dead:死亡患者],使用缩写选择,如 -type ip 表示只列出感染患者的情况,-type sp cure则会按顺序【sp, cure】列出疑似患者和治愈患者的情况,不指定该项默认会列出所有情况。
- -province 指定列出的省,如-province 福建,则只列出福建,-province 全国 浙江则只会列出全国、浙江
所以首先要分析args中的数据格式是否符合要求,可以知道list必是第一个参数;-log参数我们需要它指定的路径下面一定要具有相应的日志文件;-out所指示的文件是能够创建的;-date,-province,-type的参数值是固定值或者固定形式的。根据这些参数和参数值从而筛选得到每个省份的各种人的数值。
3.3输出分析
程序会读取-log指定目录下的所有日志,然后处理日志和命令,在-out指定目录下生成.txt文件列出2020-01-22全国和所有省的情况(全国总是排第一个,别的省按拼音先后排序),例如:
全国 感染患者22人 疑似患者25人 治愈10人 死亡2人
福建 感染患者2人 疑似患者5人 治愈0人 死亡0人
浙江 感染患者3人 疑似患者5人 治愈2人 死亡1人
// 该文档并非真实数据,仅供测试使用
因此可以建一个类来存放日志中提及省的各种信息并且构造一个处理该省要输出的信息的方法,再建一个数组存放这些类的对象。最后遍历数组,输出各省需要的信息。
4.设计实践过程
4.1 Province类
保存需要的省的各种信息,供文件输入输出。
<img src="https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217133805199-849559622.png" width="500"style="border-radius: 10px; border: 2px solid"/>
4.2 Commands类
保存命令行信息,供程序后续执行所需。
- 将输入的string[] args,用split()分解,得到参数和参数值
- 判断参数的类型(-log, -out, -date, -type, -province)
- 判断参数值格式是否合法
- 以上判断正确后保存到Commands,否则输出错误提示,退出程序
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217134520644-881887846.png)
5.代码说明
5.1 InfectStatistic类
成员变量:
static ArrayList<Province> provincesList = new ArrayList<Province>();
static String[] provincesRefered = {"全国", "安徽", "北京", "重庆", "福建", "甘肃", "广东",
"广西", "贵州", "海南", "河北", "河南", "黑龙江", "湖北", "湖南", "吉林", "江苏",
"江西", "辽宁", "内蒙古", "宁夏", "青海", "山东", "山西", "陕西", "上海", "四川",
"天津", "西藏", "新疆", "云南", "浙江"};
成员函数:
public static void main(String[] args) {...}
内部类:
class Province {...}
class Commands {...}
class FileUtil {...}
5.2 Province类
成员变量:
private String name;
private int num_infect;
private int num_cure;
private int num_dead;
private int num_suspect;
构造函数:
public Province(String name) {
this.name = name;
this.num_cure = 0;
this.num_dead = 0;
this.num_infect = 0;
this.num_suspect = 0;
}
成员函数:
//返回判断要输出的字符串
public String toString(Commands cmds) {...}
//按拼音排序。返回序号
public int compareByName(Province p) {
Collator c = Collator.getInstance(Locale.CHINA);
int numForName = c.compare(this.getName(), p.getName());
return numForName;
}
//数据增加
public void addNumInfect (int num) {
this.num_infect += num;
}
public void addNumSuspect (int num) {...}
public void addNumCure (int num) {...}
public void addNumDead (int num) {...}
//数据减少
public void subNumInfect (int num) {
this.num_suspect -= num;
}
public void subNumSuspect (int num) {...}
public void subNumCure (int num) {...}
public void subNumDead (int num) {...}
public String getName() {
return this.name;
}
5.2 Commands类
成员变量:
String log;
String out;
String date;
ArrayList<String> type;
ArrayList<String> province;
5.3 FileUtil类
成员函数:
//判断指定的Province对象是否存在,存在返回1,否则返回-1
public int isProvinceExit(String name, ArrayList<Province> list) {
if (list.isEmpty()) {
return -1;
}
else {
for (Province province : list) {
if (province.getName().equals(name)) {
return list.indexOf(province);
}
}
}
return -1;
}
//输出到指定文件
public void outPut(ArrayList<Province> list,Commands cmds) {
BufferedWriter bWriter = new BufferedWriter(new FileWriter(cmds.out));
//将"全国"数据复制到national中,从列表中删除并将列表排序后,再插入到列表第一的位置
Province national = list.get(0);
list.remove(0);
list.sort(Province::compareByName);
list.add(0, national);
//遍历列表 输出
for (Province p : list) {
String message = p.toString(cmds);
if (!message.equals("")) {
bWriter.write(message);
bWriter.newLine();
}
}
bWriter.write("// 该文档并非真实数据,仅供测试使用");
bWriter.close();
}
//提取字符串中的数字
public String saveDigit(String a) {
String regEx="[^0-9]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(a);
return m.replaceAll("");
}
//数据增加
public void addNum(String type, String number, ArrayList<Province> list, int index) {
int num = Integer.parseInt(saveDigit(number));
if (type.equals("infect")) {
list.get(index).addNumInfect(num);
list.get(0).addNumInfect(num);
}
else if (type.equals("suspect")) {...}
else if (type.equals("cure")) {...}
else {...}
}
//数据减少
public void subNum(String type, String number, ArrayList<Province> list, int index) {
int num = Integer.parseInt(saveDigit(number));
if (type.equals("infect")) {
list.get(index).subNumInfect(num);
list.get(0).subNumInfect(num);
}
else if (type.equals("suspect")) {...}
}
//过滤并判断要读取指定目录下的.log.txt,返回文件名组成的字符串数组
public String[] readLog(Commands cmds) {...}
6. 单元测试截图与描述
所用数据为example文件夹中所提供的log日志文件,总计10个测试用例 耗时如下:
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217153015702-1933740292.png)
6.1 测试用例01
本次测试采用-date为2020-01-23,无-type和-province参数,主要测试能否输出2020-01-23日及以前的累加数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217153440100-281867790.png)
应输出2020-01-22和2020-01-23日志中提及的所有省份包括"全国"累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217153601133-825118548.png)
6.2 测试用例02
本次测试采用无-date、-type和-province参数,主要测试不存在任何参数时,能否输出全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217154553152-29937217.png)
应输出2020-01-22、2020-01-23、2020-01-27日志中提及的所有省份包括"全国"累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217154839063-586623667.png)
6.3 测试用例03
本次测试采用-type 为 ip cure,无-date和-province参数,主要测试能否输出指定类型和顺序的全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217155113649-1825844193.png)
应输出2020-01-22、2020-01-23、2020-01-27日志中提及的所有省份包括"全国" 感染患者和治愈累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217155541913-664683266.png)
6.4 测试用例04
本次测试采用-province 为 全国 福建,无-date和-type参数,主要测试能否输出指定省份的全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217160018429-826575062.png)
应输出2020-01-22、2020-01-23、2020-01-27日志中全国和福建累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217160433197-738900600.png)
6.5 测试用例05
本次测试采用-type 为 ip cure,-province 为 福建 湖北,无-date参数,主要测试-type和-province组合能否输出指定省份指定类型的全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217203132724-1045610210.png)
应输出2020-01-22、2020-01-23、2020-01-27日志中福建和湖北的感染患者和治愈人数累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217203854343-41998594.png)
6.6 测试用例06
本次测试采用-province 为 全国 福建 上海,无-date和-type参数,主要测试能否输出日志中未提及但被指定的省份的全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217204230423-368698202.png)
应输出2020-01-22、2020-01-23、2020-01-27日志中全国 福建 以及上海累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217204423511-622771377.png)
6.7 测试用例07
本次测试采用-province 为 全国 湖北 安徽,-type 为 sp dead,-date 为 2020-01-22,主要测试-date、-type和-province换顺序组合能否输出指定的省份指定类型的全部数据并按省份拼音排序。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217205208521-315421370.png)
应输出2020-01-22日志中全国 湖北 以及安徽的疑似患者和死亡人数累计后的全部信息,并按全国 安徽 湖北的顺序输出
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217205230744-820282173.png)
6.8 测试用例08
本次测试采用-province 为 全国 福建 上海,-type 为 dead ip cure sp,无-date参数,主要测试-type的参数换个顺序能否按指定类型顺序输出指定的省份指定类型的全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217210054626-925561262.png)
应输出2020-01-22、2020-01-23、2020-01-27日志中全国 福建 以及上海累计后的全部信息,并按死亡 感染患者 治愈 疑似患者的顺序输出
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217210134641-838102781.png)
6.9 测试用例09
本次测试采用-province 为 全国 加利福尼亚 福建,无-date和-type参数,主要测试能否输出设定范围外省份的全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217210537933-1413906870.png)
应输出2020-01-22、2020-01-23、2020-01-27日志全国 福建累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217210555430-903502943.png)
6.10 测试用例10
本次测试采用-province 为 全国 加利福尼亚 福建,-date 为 2020-01-24,无-type参数,主要测试在合理日期范围内但不存在该日日志的情况下能否输出该日及之前的全部数据。
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217211137362-1777927259.png)
应输出2020-01-22、2020-01-23日志全国 福建累计后的全部信息
![](https://img2018.cnblogs.com/blog/1927227/202002/1927227-20200217211138562-606316660.png)
7 代码规范
点击进入-> codestyle
8 心路历程
通过第二次作业,我重新温习了java的io操作,也对需求分析有了进一步的认识,更重要通过项目的进行更加深刻体会到预定设计方案的重要性,并且学会了使用junit进行单元测试,提高了测试效率。另外,新制定的代码规范也提高的我代码的可读性。整体下来发现对设计模式的理解还不到位,需加强。
9 第一次作业中技术路线图相关的仓库
jQuery——jQuery架构设计与实现(2.1.4版本)
jQuery干货教程
第一章:理解架构
第二章:核心机制
第三章:回调模型
第四章:异步编程
第五章:数据缓存
第六章:队列操作
第七章:模块加载
第八章:选择器引擎
第九章:节点遍历
第十章:文档处理
第十一章:样式操作
第十二章:属性操作
第十三章:事件体系
第十四章:AJAX交互
第十五章:动画引擎
这是任何人都可以用来学习前端的实践手册, 它概述并讨论了前端工程的实践: 该如何学习以及实践时该使用什么工具.
撰写该手册的目的有两个: 一是为潜在以及正在实践的前端开发人员提供一个包括学习资料和开发工具的专业资源; 二是该手册可以被管理者, CTO, 讲师和猎头用来作为洞察前端开发的实践.
该手册的内容支持Web技术(HTML, CSS, DOM, 和 JavaScript), 并且手册提供的解决方案都直接建立在这些开放的技术之上. 手册中所引用的素材和讨论都是最好的或者当前前端开发者们需要面对的问题.
该手册不应该被视为一个前端开发者对所有可用资源的综合大纲, 其价值在于简洁, 专注和及时管理足够的分类信息, 不致于任何人沉浸在任何一个特定的主题.
该手册会每年发布一个更新内容.
Front-end-tutorial——前端涉及的所有知识体系
众所周知,前端发展如火如荼,日新月异,而且很长一段时间内都将如此。这份由晚晴幽草轩轩主正在维护的教程列表;旨在为前端学习,技能提升,视野扩展,资料查找等行个方便。将会在日常工作探索、学习中,持续保持更新,增新优之章,除旧失之文;尽可能使得这份列表保持简练,以避免信息过重且冗杂;望其能在浩如烟海的讯息中,堪有所用。
twbs/bootstrap——Bootstrap 的 Github 帐户,著名的响应式网页设计架构
Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML、CSS、JavaScript 开发的简洁、直观、强悍的前端开发框架,使得 Web 开发更加快捷。Bootstrap提供了优雅的HTML和CSS规范,它即是由动态CSS语言Less写成。Bootstrap一经推出后颇受欢迎,一直是GitHub上的热门开源项目,包括NASA的MSNBC(微软全国广播公司)的Breaking News都使用了该项目。 国内一些移动开发者较为熟悉的框架,如WeX5前端开源框架等,也是基于Bootstrap源码进行性能优化而来。
全面讲解了JavaScript框架设计及相关的知识,主要内容包括种子模块、语言模块、浏览器嗅探与特征侦测、类工厂、选择器引擎、节点模块、数据缓存模块、样式模块、属性模块、PC端和移动端的事件系统、jQuery的事件系统、异步模型、数据交互模块、动画引擎、MVVM、前端模板(静态模板)、MVVM的动态模板、性能墙与复杂墙、组件、jQuery时代的组件方案、avalon2的组件方案、react的组件方案等。