软工实践寒假作业(2/2)

这个作业属于哪个课程 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] = '';
		}
		else if (s == "-out")
		{
			int c = 0;
			while (i < size && com[i] != ' ')
			{
				outpath[c] = com[i];
				i++, c++;
			}
			outpath[c] = '';
		}
		else if (s == "-date")
		{
			int c = 0;
			while (i < size && com[i] != ' ')
			{
				date[c] = com[i];
				i++, c++;
			}
			cc = c;
			date[c] = '';
		}
		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<in.size();i++)In[i]=in[i];
					In[in.size()]='';
					char *p;
					p=U2G(In);
					string tmp;
					for(int i=0;p[i]!='';i++)tmp=tmp+p[i];
					if (tmp[0] == '/' && tmp[1] == '/')continue;
					LineDetail(tmp);
				}
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<<fl1<<' '<<fl2<<' '<<f1<<' '<<f2<<' '<<num<<endl;
	Change(province1, province2, type1, type2, num, l);

已经提取完省份以及人数后,针对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 << "
";
			}
		}
	}

六.单元测试截图和描述

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支持案例

原文地址:https://www.cnblogs.com/LOCI/p/12332862.html