这个作业属于哪个课程 | 2020春|S班(福州大学) |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 | 开发一个疫情统计程序 |
作业正文 | 寒假作业2 |
其他参考文献 | 博客园 |
1、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
Estimate | 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 1120 | 1230 |
Analysis | 需求分析 (包括学习新技术) | 180 | 200 |
Design Spec | 生成设计文档 | 30 | 25 |
Design Review | 设计复审 | 10 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 45 |
Design | 具体设计 | 90 | 100 |
Coding | 具体编码 | 600 | 650 |
Code Review | 代码复审 | 30 | 50 |
Test | 测试(自我测试,修改代码,提交修改) | 120 | 150 |
Reporting | 报告 | 120 | 130 |
Test Repor | 测试报告 | 30 | 40 |
Size Measurement | 计算工作量 | 30 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 60 |
合计 | 1270 | 1410 |
2、解题思路描述
首先,程序对命令行的输入进行处理,分析出list命令所带的参数,除一定有的log和out参数,是否有带date参数、type参数,province参数,然后,提取出所带参数的参数值,并保存;处理日志目录下符合日期要求的日志文件,读取文件中非注释的每行,并更新省份确诊患者,疑似患者,治愈,死亡的人数;统计出各省的情况后,统计全国的情况;结合命令是否带type参数,province参数,将统计结果输出到文件中。
3、设计实现过程
新建Nation类(国家类)用于记录整个国家的疫情情况,Province类(省类)用于记录省份的疫情情况。创建InfectStatistic类静态成员变量allProvince(ArrayList 类型)用来记录省份实例对象,创建一些静态成员变量(String类型或String[]类型)来记录命令的参数值等等。
4、代码说明
1.对命令行输入的命令进行处理
public static void analysisOfCommand(String[] args)
{
for (int i = 0;i < args.length;i++)
{
if (args[i].equals("-log"))
{
commandArgsFlag[0]++;
pathOfLog = args[i + 1];
}
else if (args[i].equals("-out"))
{
commandArgsFlag[1]++;
pathOfOutput = args[i + 1];
}
else if (args[i].equals("-date"))
{
commandArgsFlag[2]++;
dateString = args[i + 1];
}
else if (args[i].equals("-type"))
{
commandArgsFlag[3]++;
for (int k = 0;k < paramentersOfType.length;k++)
{
paramentersOfType[k] = new String();
}
int cnt = 0;
for (int j = i + 1;j < args.length && args[j].startsWith("-") == false;j++)
{
paramentersOfType[cnt++] = args[j];
}
}
else if (args[i].equals("-province"))
{
commandArgsFlag[4]++;
for (int k = 0;k < paramentersOfProvince.length;k++)
{
paramentersOfProvince[k] = new String();
}
int count = 0;
for (int j = i + 1;j < args.length && args[j].startsWith("-") == false;j++)
{
paramentersOfProvince[count++] = args[j];
}
}
}
}
2.按行读取文件
try
{
InputStreamReader isr = new InputStreamReader(
new FileInputStream(pathOfLog+allLogFilesName[i]), "UTF-8");
BufferedReader br = new BufferedReader(isr);
while ((oneLineOfFile = br.readLine()) != null
&& oneLineOfFile.length() != 0 //不读取空行
&& oneLineOfFile.startsWith("//") == false) //不读取注释行
{
//System.out.println(oneLineOfFile);
//统计省份的感染人数,疑似人数,治愈人数和死亡人数
getProvincialInformation(oneLineOfFile);
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
3.统计省份的感染人数,疑似人数,治愈人数和死亡人数
public static void getProvincialInformation(String oneLineOfFile)
{
String[] splitString = oneLineOfFile.split(" ");
int countOfPeople = getStringNumber(splitString[splitString.length - 1]);
addToArrayList(splitString[0]); //将省份加入动态数组
if (splitString.length == 3)
{
for (int i = 0;i < allProvince.size();i++)
{
if (allProvince.get(i).provinceName.equals(splitString[0]))
{
if (splitString[1].equals("死亡"))
{
allProvince.get(i).dead += countOfPeople;
allProvince.get(i).ip -= countOfPeople;
break;
}
else if (splitString[1].equals("治愈"))
{
allProvince.get(i).cure += countOfPeople;
allProvince.get(i).ip -= countOfPeople;
break;
}
}
}
}
else if (splitString.length == 4)
{
for (int i = 0;i < allProvince.size();i++)
{
if (allProvince.get(i).provinceName.equals(splitString[0]))
{
if (splitString[1].equals("新增")
&& splitString[2].equals("感染患者"))
{
allProvince.get(i).ip += countOfPeople;
break;
}
else if (splitString[1].equals("新增")
&& splitString[2].equals("疑似患者"))
{
allProvince.get(i).sp += countOfPeople;
break;
}
else if (splitString[1].equals("疑似患者")
&& splitString[2].equals("确诊感染"))
{
allProvince.get(i).sp -= countOfPeople;
allProvince.get(i).ip += countOfPeople;
break;
}
else if (splitString[1].equals("排除")
&& splitString[2].equals("疑似患者"))
{
allProvince.get(i).sp -= countOfPeople;
break;
}
}
}
}
else if (splitString.length == 5)
{
addToArrayList(splitString[3]); //将省份加入动态数组
for (int i = 0;i < allProvince.size();i++)
{
if (allProvince.get(i).provinceName.equals(splitString[0]))
{
if (splitString[1].equals("感染患者"))
{
allProvince.get(i).ip -= countOfPeople;
}
else if (splitString[1].equals("疑似患者"))
{
allProvince.get(i).sp -= countOfPeople;
}
}
else if (allProvince.get(i).provinceName.equals(splitString[3]))
{
if (splitString[1].equals("感染患者"))
{
allProvince.get(i).ip += countOfPeople;
}
else if (splitString[1].equals("疑似患者"))
{
allProvince.get(i).sp += countOfPeople;
}
}
}
}
}
4.将统计结果输出到指定txt文件中
public static void outputToTxtFile(String resultString)
{
File txtFile = new File(pathOfOutput);
try
{
if(txtFile.exists()) //如果有同名文件,先删除那个文件
{
txtFile.delete();
}
txtFile.createNewFile();
FileOutputStream writerStream = new FileOutputStream(txtFile);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(writerStream, "UTF-8"));
writer.write(resultString);
writer.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
5、单元测试
1.获取日志目录下文件名中的最大日期
2.提取字符串当中的数字并转换成整数返回
3.各省份按省份名进行排序
4.测试各种命令
@Test
public void testMain1() {
String string1 = "list -log D:\\log\\ -out D:\\ListOut1.txt -date 2020-01-22";
String[] args1 = string1.split(" ");
try
{
InfectStatistic.main(args1);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Test
public void testMain2() {
String string2 = "list -log D:\\log\\ -out D:\\ListOut2.txt -date 2020-01-22 -province 福建 河北";
String[] args2 = string2.split(" ");
try
{
InfectStatistic.main(args2);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Test
public void testMain3() {
String string3 = "list -log D:\\log\\ -out D:\\ListOut3.txt -date 2020-01-23 -type cure dead ip -province 全国 浙江 福建";
String[] args3 = string3.split(" ");
try
{
InfectStatistic.main(args3);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Test
public void testMain4() {
String string4 = "list -log D:\\log\\ -out D:\\ListOut4.txt -type cure dead ip -province 全国 浙江 福建 安徽";
String[] args4 = string4.split(" ");
try
{
InfectStatistic.main(args4);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Test
public void testMain5() {
String string5 = "list -log D:\\log\\ -out D:\\ListOut5.txt -date 2020-01-23 -type dead ip -province 全国";
String[] args5 = string5.split(" ");
try
{
InfectStatistic.main(args5);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Test
public void testMain6() {
String string6 = "list -log D:\\log\\ -out D:\\ListOut6.txt -date 2020-01-23 -type cure dead -province 浙江 全国 福建";
String[] args6 = string6.split(" ");
try
{
InfectStatistic.main(args6);
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Test
public void testMain7() {
String string7 = "list -log D:\\log\\ -out D:\\ListOut7.txt -date 2020-01-27 -province 湖北";
String[] args7 = string7.split(" ");
try
{
InfectStatistic.main(args7);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
6、单元测试覆盖率优化和性能测试
7、git仓库链接、代码规范链接
仓库链接:https://github.com/hydc123/InfectStatistic-main
代码规范链接:https://github.com/hydc123/InfectStatistic-main/blob/master/221701114/codestyle.md
8、心路历程和收获
通过这次的作业,我学习到了GitHub和GitDeskTop的一些使用方法,了解了一些基本的Git命令。另外,拿到需求写代码之前,一定要认真分析清楚具体的需求,设计好数据结构等等,需求没有分析清楚,后面代码重新修改,会花费比较多的时间。上次作业的技术路线,我写的是java,所以这次想用java语言来完成作业,一开始感觉不顺手,因为java的课上完后,较少用java来写代码。以后要多动手编程,加深对知识的理解。本次作业还让我对单元测试有所了解,知道如何用MyEclipse进行简单的单元测试。总之,这次作业使我收获很大。
9、技术路线图相关的5个仓库
- 仓库1:【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识。
仓库链接 - 仓库2:可以使用Spring Boot创建独立的Java应用程序,可以使用java -jar或更传统的WAR部署启动该应用程序 。
仓库链接 - 仓库3:Hibernate ORM是一个为应用程序,库和框架提供对象/关系映射(ORM)支持的库。
仓库链接 - 仓库4:JavaWeb
仓库链接 - 仓库5:JavaEE框架
仓库链接