这个作业属于哪个课程 | 2020春|S班 (福州大学) |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) 作业要求 |
这个作业的目标 | 使自己能够开始思考和规划接下来的学习 |
作业正文 | 软工实践寒假作业(2/2) |
其他参考文献 | 博客园 |
二.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 40 | 45 |
Estimate | 估计这个任务需要多少时间 | 30 | 40 |
Development | 开发 | 800 | 950 |
Analysis | 需求分析 (包括学习新技术) | 150 | 150 |
Design Spec | 生成设计文档 | 50 | 50 |
Design Review | 设计复审 | 45 | 30 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 45 |
Design | 具体设计 | 90 | 90 |
Coding | 具体编码 | 600 | 700 |
Code Review | 代码复审 | 50 | 40 |
Test | 测试(自我测试,修改代码,提交修改) | 200 | 220 |
Reporting | 报告 | 120 | 160 |
Test Repor | 测试报告 | 30 | 10 |
Size Measurement | 计算工作量 | 20 | 15 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 50 | 60 |
合计 | 2305 | 2605 |
三.解题思路
-
处理命令
命令有-log -out -date -type -province
这个几个命令行参数
进行一遍扫描后把各自的的参数都处理出来,例如人员类型一共有四种,参数里只提到了三种,则将人员类型以输入顺序存
在数组里便于之后的判断。 -
遍历文件夹
采用递归的方式,找到符合条件的文件,即后缀为.log.txt
的文件,然后开始进行行读入 -
数据更新
建立二维数组,对应身份和人员种类,并初始化为0
逐行扫描日志,得到每行提及的省以及相应的动词,根据日志中会出现的8种情况,进行判断,更新数据。 -
输出
通过以上的数据,遍历二维数组,判断是否需要输出,并以正确的格式输出数据。
四.设计实现
-
处理命令时,如果有进行省份输入,则用map保存,并标注有省份的限制,如果没有标注,在后期输出的时候就要遵守另一组规则。
在处理日志文件时,对所有涉及到的省份用另一个map保存。所以在输出的时候要进行特判。
-
保存人员数目的二维数组应初始化为0,在遍历日志文件的时候,如果文件的日期大于命令的日期(如果有设置-date),则
应该停止检测。 -
全国的数据在输出函数中处理,其将所有省份的记录加起来,得到结果。
五.代码说明
对命令进行分析处理
if (s == "-log")
{
int c = 0;
while (i < size && com[i] != ' ')
{
inpath[c] = com[i];
i++, c++;
}
inpath[c] = '\0';
}
else if (s == "-out")
{
int c = 0;
while (i < size && com[i] != ' ')
{
outpath[c] = com[i];
i++, c++;
}
outpath[c] = '\0';
}
else if (s == "-date")
{
int c = 0;
while (i < size && com[i] != ' ')
{
date[c] = com[i];
i++, c++;
}
cc = c;
date[c] = '\0';
}
else if (s == "-type")
{
int c = 1;
string ss = "";
while (i < size)
{
ss = ss + com[i];
i++;
if (com[i] == ' ' || i == size)
{
if (ss == "ip")mi2["感染患者"] = c, type[c++] = "感染患者";
else if (ss == "sp")mi2["疑似患者"] = c, type[c++] = "疑似患者";
else if (ss == "cure")mi2["治愈"] = c, type[c++] = "治愈";
else if (ss == "dead")mi2["死亡"] = c, type[c++] = "死亡";
i++;
ss = "";
}
}
type_num = c;
CheckType(c);
}
else if (s == "-province")
{
int c = 0;
while (i < size && (com[i] >= 'z' || com[i] <= 'a') && com[i] != '-')
{
if (com[i] == ' ')mi1[province[c]] = 1, c++;
else province[c] = province[c] + com[i];
i++;
}
if (i == size)mi1[province[c]] = 1, c++;
if (com[i] >= 'z' || com[i] <= 'a')i--;
province_num = c;
}
else if (com[i] == ' ');
else i--;
}
对符合条件的每行数据进行处理
while (getline(fin, in))
{
char In[200];
for(int i=0;i
int province1 = 0, province2 = 0;
string s = "";
int l = 0;
for (int j = 0; j < tmp.size(); j++)
{
if (tmp[j] == ' ')
{
if (!mi.count(s))
{
s = "";
continue;
}
mi3[s] = 1;
if (mi[s] >= 100)l = mi[s];
else if (province1 == 0)province1 = mi[s];
else province2 = mi[s];
s = "";
}
else s = s + tmp[j];
}
int type1 = 0, type2 = 0;
string ss = "";
for (int j = 0; j < tmp.size(); j++)
{
if (tmp[j] == ' ')
{
if (!mi2.count(ss))
{
ss = "";
continue;
}
if (type1 == 0)type1 = mi2[ss];
else type2 = mi2[ss];
ss = "";
}
else
{
ss = ss + tmp[j];
}
}
int num = Num(tmp);
// cout<
已经提取完省份以及人数后,针对8种可能的情况进行判断
if (province2 == 0 && type2 == 0)
{
if (l == 100)out[province1][type1] += num;
else if (l == 101)out[province1][type1] -= num;
else if (l == 102)
{
out[province1][mi2["感染患者"]] -= num;
out[province1][mi2["治愈"]] += num;
}
else
{
out[province1][mi2["死亡"]] += num;
out[province1][mi2["感染患者"]] -= num;
}
}
else if (province2 == 0 && type2 != 0)
{
out[province1][mi2["疑似患者"]] -= num;
out[province1][mi2["感染患者"]] += num;
}
else
{
out[province1][type1] -= num;
out[province2][type1] += num;
}
将各省的数据加起来得到全国数据
for (int i = 2; i < 36; i++)
{
for (int j = 1; j < type_num; j++)
{
out[1][j] += out[i][j];
}
}
进行判断后输出最后结果
for (int i = 1; i < 36; i++)
{
bool flg = province_num == 0 && (mi3.count(province_of[i]) || i == 1);
if (mi1.count(province_of[i]) || flg)
{
cout << province_of[i] << ' ';
for (int j = 1; j < type_num; j++)
{
cout << type[j] << out[i][j] << "人 ";
}
if (mi1[province_of[i]] == 1 || province_num == 0)
{
cout << "\n";
}
}
}
六.单元测试截图和描述
TEST_METHOD(TestMethod1)
{
analysis a;
string s1 = "list -log D:\log -date 2020-01-22 -out D:\out1.txt -province 全国 福建 -type sp";
string ss1 = "2020-01-22 全国福建 疑似患者 ";
Assert::AreEqual(ss1,a.begin(s1));
string s2 = "list -log D:\log -out D:\out2.txt -type sp cure";
string ss2 = "疑似患者治愈 ";
Assert::AreEqual(ss2, a.begin(s2));
string s3 = "list -log D:\log -date 2020-01-22 -out D:\out3.txt -province 全国 福建";
string ss3 = "2020-01-22 全国福建 感染患者疑似患者治愈死亡 ";
Assert::AreEqual(ss3, a.begin(s3));
}
TEST_METHOD(TestMethod2)
{
analysis b;
string s1 = "list -log D:\log -date 2020-01-23 -out D:\out4.txt -province 福建 -type sp";
string ss1 = "2020-01-23 福建 疑似患者 ";
Assert::AreEqual(ss1, b.begin(s1));
string s2 = "list -log D:\log -out D:\out5.txt -type sp";
string ss2 = "疑似患者 ";
Assert::AreEqual(ss2, b.begin(s2));
string s3 = "list -log D:\log -date 2020-01-23 -out D:\out6.txt -province 全国 福建";
string ss3 = "2020-01-23 全国福建 感染患者疑似患者治愈死亡 ";
Assert::AreEqual(ss3, b.begin(s3));
}
TEST_METHOD(TestMethod3)
{
analysis b;
string s1 = "list -log D:\log -date 2020-01-23 -out D:\out7.txt -province 全国 福建";
string ss1 = "2020-01-23 全国福建 ";
Assert::AreEqual(ss1, b.begin(s1));
string s2 = "list -log D:\log -out D:\out8.txt -province 湖北 -type sp cure";
string ss2 = "疑似患者 ";
Assert::AreEqual(ss2, b.begin(s2));
string s3 = "list -log D:\log -out D:\out9.txt -province 全国";
string ss3 = "全国 感染患者疑似患者治愈死亡 ";
Assert::AreEqual(ss3, b.begin(s3));
string s3 = "list -log D:\log -out D:\out10.txt";
string ss3 = "全国 感染患者疑似患者治愈死亡 ";
Assert::AreEqual(ss3, b.begin(s3));
}
......
同时还检测了具体的人员数目
TEST_METHOD(TestMethod5)
{
analysis c;
string sss1 = "list -log D:\log -date 2020-01-22 -out D:\out1.txt -province 全国 福建 -type sp";
c.begin(sss1);
c.Out();
Assert::AreEqual((int)22, c.check);
Assert::AreEqual((int)22, c.Detail("全国", "疑似患者"));
Assert::AreEqual((int)2, c.Detail("全国", "治愈"));
Assert::AreEqual((int)0, c.Detail("福建", "治愈"));
}
第一个输出文档
第二个输出文档
第三个输出文档
第四个输出文档
第五个输出文档
第六个输出文档
第七个输出文档
第八个输出文档
第九个输出文档
第十个输出文档
七.单元测试覆盖率优化和性能测试
- 起初写的测试覆盖率很低,因为我也没把所有函数都拿去测试,虽然它们最终的结果都是对的,后来进行了一些改进。
原本代码实现,需要在遍历所有的省份,再进行核对看是否需要进行增加或者减少的操作。
后来觉得这步进行的很多余,于是就把在日志中的省份核对这个步骤取消,所有的省份都有对应的代号,每个省份都进行
更改数据操作,无论命令是否有要求,在输出部分解决命令的具体要求。
int province1 = 0, province2 = 0;
string s = "";
int l = 0;
for (int j = 0; j < tmp.size(); j++)
{
if (tmp[j] == ' ')
{
if (!mi.count(s))
{
s = "";
continue;
}
mi3[s] = 1;
if (mi[s] >= 100)l = mi[s];
else if (province1 == 0)province1 = mi[s];
else province2 = mi[s];
s = "";
}
else s = s + tmp[j];
}
八.代码规范的链接
https://github.com/LOCICC/InfectStatistic-main/blob/master/221701204/codestyle.md
九.心路历程和收获
起初题目意思理解错了,以为是从日志文件中找符合条件的信息,等差不多打完代码后才发现写错了。所以这件事是我明
白,在正式开始做之前一定要审清楚需求,再开始动笔。在编写代码的过程中遇到了许多问题,主要的问题是字符的处理,
以及单元测试。我之前从来没有进行过特别系统的测试,所以这次测试花了我比较多的时间,中途出现了一些显示不出测试
结果的问题,后来才明白怎么做。希望下次能有所改进。制作项目的时候能更加熟练。
这次项目锻炼了我收获使用github的使用能力,可以查看各种大佬的代码,并且能为自己所用。学习软件工程首先要明
白自己的学习目标究竟是什么,根据自己的实际工作出发,有针对性的在相应的学习方向上进行提高,制定出详细的学习规划。
在写软件的时候,我们首先要有整体的结构和思路,这样才能照着一定的思想一定思路去写下去。同时认识到了软件工程实践
特别重要,需要花大量的时间去学习。
十.github上的相关学习
1.spring-boot
https://github.com/LOCICC/spring-boot
可以使用Spring Boot创建独立的Java应用程序,可以使用java -jar或更传统的WAR部署来启动它。 还提供了运行Spring脚本的命令行工具。
2.spring-framework
https://github.com/LOCICC/spring-framework
Spring提供了Java编程语言以外的所有所需内容,可用于为各种场景和体系结构创建企业应用程序。
3.Python
用Python实现的多种算法(用于教育),简单的学习,效率不一定高。
https://github.com/LOCICC/Python
4.Python的脚本
https://github.com/LOCICC/Python-1
模拟登录知乎,对目录下所有文件计数,Excel文件读入数据库,批量修改文件名,获取当前CPU状态,存储到Influxdb
5.JavaEETest
https://github.com/LOCICC/JavaEETest
Spring中的事件发送与处理案例,Spring Aware使用案例,初识SpringBoot案例,SpringBoot开发Web项目并且添加HTTPS支持案例