软工实践寒假作业(2/2)
GitHub仓库地址
这个作业属于哪个课程 | 班级 |
---|---|
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 开发疫情统计程序、阅读构建之法并撰写学习记录、解题思路等 |
作业正文 | 作业正文 |
其他参考文献 | 博客、知乎相关问题 |
学习心得地址:
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 60 |
Estimate | 估计这个任务需要多少时间 | 20 | 25 |
Development | 开发 | 200 | 210 |
Analysis | 需求分析 (包括学习新技术) | 120 | 150 |
Design Spec | 生成设计文档 | 80 | 75 |
Design Review | 设计复审 | 40 | 50 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 70 |
Design | 具体设计 | 30 | 20 |
Coding | 具体编码 | 240 | 300 |
Code Review | 代码复审 | 45 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 300 | 350 |
Reporting | 报告 | 120 | 150 |
Test Repor | 测试报告 | 30 | 40 |
Size Measurement | 计算工作量 | 45 | 60 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1245 | 1650 |
解题思路
(一)了解Main函数的参数,明白在java程序中main函数的参数是一String[]的形式存储在argc中;
(二)根据上学期学习的面向对象设计,首先,对题目的需求进行分析。题目的需求如下:需要在命令行界面调用程序,传入参数。然后根据参数对日志文件进行处理。首先,命令的参数类型有多种,所以需要有List类来存储命令;
(三)正确读取命令后,就需要对日志文件进行筛选,选取符合条件的日志文件,存储在日志文件列表(FileList)中,便利日志文件列表,开始对日志文件的内容进行操作;
(四)逐行读取日志文件,使用split(" ")
,将读取的内容划分为字符串数组,对字符串的情况进行判断分类,执行相应的操作。可能出现的情况:
>1、<省> 新增 感染患者 n人
2、<省> 新增 疑似患者 n人
3、<省1> 感染患者 流入 <省2> n人
4、<省1> 疑似患者 流入 <省2> n人
5、<省> 死亡 n人
6、<省> 治愈 n人
7、<省> 疑似患者 确诊感染 n人
8、<省> 排除 疑似患者 n人
根据String[]的长度进行分类,分为3、4、5个,然后在依次判断为何操作;
(五)、计算出结果,然后输出到指定文件中。
设计与实现过程
主要步骤
主要类
1、List类来存储输入的指令和参数。List类中的具有属性:
String Log;//存储日志所存在的目录
String Out;//存储输出文件的地址
Date NowDate;//存储输入的日期
ProvinceList Provinces;//存储需要输出的省份列表,默认全国
TyepList Types;//存储需要输出的类型。默认四种类型都有
2、需要省份列表类(ProvinceList),内包含了属性
Province[] provinces;//存储个个城市
static String[] Provinces={"全国","安徽"....};//存储城市的顺序;
3、省份类(Province),属性:
String ProvinceName;//记录省份名;
int ip;//患者人数
int sp;//疑似患者人数
int cure;//治愈人数
int dead;//死亡人数
4、类型列表类(TypeList),利用HasMap存储了类型:
"ip":感染患者
"sp":疑似患者
"cure":治愈
"dead":死亡
5、将main函数的参数处理后,开始对对数据进行处理,Work类用来读取处理日志文件,并输出参数:
List list;//存储传入的参数
ProvinceList PL;//记录数据
String[] FileList;//记录日志文件列表
关键函数
一、遍历日志文件列表处理数据:dealData()
public void dealData() {
for (String str : FileList) {//遍历日志文件列表
String fileName = list.Log + "\\" + str;//日志文件地址
File file = new File(fileName);//打开日志文件
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String tempStr;
while ((tempStr = reader.readLine()) != null) {//逐行读取日志
tempStr.trim();
if (tempStr.charAt(0) != '/') {
String[] lineList = tempStr.split(" ");
Deal(lineList);//处理数据
}
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、读取字符串后,对于省份列表进行操作:Deal(String[] lineList)
public void Deal(String[] lineList) {
// System.out.println(lineList[0]+lineList.length);
if (lineList.length == 3) {
if (lineList[1].equals("死亡")) {
// 省死亡数+ 感染者数-
Add(lineList[0], "cure", FindNumber(lineList[2]));//传入省份名、类型、数字进行列表处理
Add(lineList[0], "dead", -1*FindNumber(lineList[2]));//若需要减少人数,则该为加负数即可
}
else if (lineList[1].equals("治愈")) {
// 治愈数+ 感染数-
...
}
} else if ...
三、TypeList类,用HasMap实现:
public Map Types = new HashMap();
public TypeList(String[] list) {
Types.put("ip", "感染患者");
Types.put("sp", "疑似患者");
Types.put("cure", "治愈");
Types.put("dead", "死亡");
Map Types2 = new HashMap();
if (list != null) {
for (String str : list) {
Types2.put(str, Types.get(str));
}
Types = Types2;
}
}
四、处理命令行数据Init():
static void init(String[] argc) {
String[] strs = argc;
String log = null;
String out = null;
Date date = new Date();
String[] provinces = null;
String[] types = null;
for (int i = 1; i < strs.length; i++) {
if (strs[i].equals("-log")) {//匹配log参数
log = strs[++i];
} else if (strs[i].equals("-out")) //匹配out参数
out = strs[++i];
} else if (strs[i].equals("-date")) {//匹配date参数
String[] s = strs[++i].split("-");
Calendar cal = GregorianCalendar.getInstance();
cal.set(Integer.parseInt(s[0]), Integer.parseInt(s[1]) - 1, Integer.parseInt(s[2]));
date = cal.getTime();
} else if (strs[i].equals("-type")) {//匹配type参数
....
} else if (strs[i].equals("-province")) {//匹配province参数
.....
}
list = new List(log, out, date, provinces, types);
work = new Work(list);
}
单元测试
一、使用@Before初始化数据,以方便测试:
二、测试单元
1、获取某省份指定类型的值:
2、提取字符串中的数字:
3、日志文件名与Date比较:
4、获取文件列表测试:
结果:
5、将字符串转化为Date测试:
6、数据处理测试:
结果:
7、从省份类获取某个省份测试
结果:
8、日志文件选择测试:
结果:
9、文件输出测试:
10、初始化List测试:
JUnit测试结果:
单元测试覆盖率及优化:
单元测试覆盖率:
优化后:
优化说明
将一些最终的不需要的打码进行删除,增加带代码的覆盖率。
编程风格:
codestyle.md
Github仓库
InfectStatistic-main
心路历程与收获
学习构建之法:
在第一章中,作者将航空的发展类比软件的产业,有趣的类比软件的发展。还了解到了,软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护中。作为一名软件工程的学生应该要有较好的基础,学习好基础的算法。只有把基础打牢才能够轻松的开发程序。
在第二章中,作者介绍了单元测试、回归测试、能效分析和个人软件开发流程(PSP)。测试单元,是为了在多人分部开发是,为了验证自己程序功能而进行的测试。测试单元最好是由程序编写者进行测试,因为只有编写者才最清楚程序的用途,才能更好的进行测试。回归测试是指一个模块在以前是能够正常工作的,但是加入了新的模块后出现了异常。因此需要回归测试。合理的利用效能分析工具,能够不叫好的做好程序优化的工作。最重要的是学习到了个人软件开发流程(PSP)作为一个软件工程的学生,在今后的开发中,要好好规划好学习和开发的时间,做好有规划的进行开发。
在第三章中,了解了作者所讲述的个人价值与能力的衡量,我思考怎么样才叫做是精通某种语言,让我更加坚定了学习巩固好基础的决心。不能把时间花费在解决低层次的问题。
本次的作业可以说是很艰难吧,艰难的地方在与我忽视了作业,没能够有充裕的时间去学期更多的东西,做出的计划没有很好的实施。花费了巨大的时间。没有做好时间的规划,在今后的学习中,我一定吸取这次的教训,做好时间规划,有更多的时间去更高质量地完成组作业。
技术路线图相关仓库
1、学习仓库1
该仓库是使用javascript实现是富文本编辑器,开源基于MIT协议,允许自由使用和修改代码。
2、学习仓库2
nodejs 的一个聊天软件,类似微信。模仿微信的界面,做到简单明了地聊天。
3、学习仓库3
使用nw.js构建的网易云音乐的跨平台第三方客户端。
4、学习仓库4
作者想把自己学习JQuery的知识点,代码技巧,设计思想,代码模式能很好的表达出来。
5、学习仓库5
通过javascript写的一个 Flappy Bird的项目