欢迎来到Wzzzq的博客

 

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

这个作业属于哪个课程 2020春|S班(福州大学)
这个作业的要求在哪里 寒假作业(2/2)
这个作业的目标 疫情统计
作业正文 Wzzzq的作业(2/2)
其他参考文献 百度、CSDN博客、b站

一、GitHub仓库

作业的主仓库:https://github.com/kofyou/InfectStatistic-main/pulls
我的Github仓库:https://github.com/WZQ233/InfectStatistic-main

二、PSP表格

PSP各个阶段 Personal Software Proces Stages 预计耗时(分钟) 实践耗时
Planning 计划 30 30
Estimate 估计这个任务需要多少时间 30 30
Development 开发 1810 2240
Analysis 需求分析(包括学习新技术) 800 980
Design Spec 生成设计文档 40 40
Design Review 设计复审 30 30
Coding Standard 代码规范(为目前的开发制定合适的规范) 60 80
Design 具体设计 80 100
Coding 具体编码 500 580
Code Review 代码复审 80 80
Test 测试(自我测试,修改代码,提交修改) 300 350
Reporting 报告 470 510
Test Report 测试报告 60 80
Size Measurement 计算工作量 60 50
Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 350 380
合计 2310 2780

三、解题思路

思考

  • 通过浏览题目可知需要通过命令行对指定文件夹下的日志文件进行处理,对全国和各省在某日的感染情况进行统计,后生成output.txt文件。
  • 题目的输入为命令行参数及日志文件,输出为output.txt文件。
  • 大致思路为根据所给日志文件路径读取日志文件并处理,并输出至指定的文件中,且根据其他参数来调整输出的内容。
  • 在读取参数和日志文件时应当进行适当的非法检测,并抛出异常输出错误原因结束程序。

思路

资料

  • 大致阅读班级附录所给的学习资源,对于要使用到的部分仔细阅读。
  • 根据所需要的技术在网上查阅相关教程,如在博客园上学习各种参数处理,哔哩哔哩上学习GitHub及GithubDesktop的使用等。

四、设计思路

编写一个异常类和主类来实现该程序,通过主类中的各种函数来实现题目所需功能,在出现错误时,异常类报错并结束程序。先通过inspectParameter()对命令行的参数进行检验,如果合法则调用execLog()函数对日志文件进行读取,execLog()函数中调用execFile()函数和outputFile()来保存数据和输出文件。其中用List来记录type和province参数的输入情况,用LinkedHashMap来存储日志文件中的数据。与此同时通过异常类来捕获异常并结束程序。

流程

五、代码说明

  • InfectStatistic主类说明
    主类中主要变量及用途
        public String logPath;		//保存日志路径
	public String outPath;		//保存输出路径
	public String dateStr;
	
	boolean typeIsExist;
	boolean provinceIsExist;
	
	public List<String> types = new ArrayList<String>();
	public List<String> provinces = new ArrayList<String>();
	
	public String[] args;		//保存命令
	public String[] typeStr = {"ip","sp","crue","dead"};            //保存类型
	public String[] provinceStr = {"全国", "安徽", "澳门" ,"北京", "重庆", "福建","甘肃",
			"广东", "广西", "贵州", "海南", "河北", "河南", "黑龙江", "湖北", "湖南", "吉林",
			"江苏", "江西", "辽宁", "内蒙古", "宁夏", "青海", "山东", "山西", "陕西", "上海",
			"四川", "台湾", "天津", "西藏", "香港", "新疆", "云南", "浙江"};	//保存省份
	
	public LinkedHashMap<String,Integer> ip = new LinkedHashMap<String,Integer>();	//保存各省的感染患者人数
	public LinkedHashMap<String,Integer> sp = new LinkedHashMap<String,Integer>(); 	//保存各省的疑似患者人数
	public LinkedHashMap<String,Integer> cure = new LinkedHashMap<String,Integer>();	//保存各省的治愈人数
	public LinkedHashMap<String,Integer> dead = new LinkedHashMap<String,Integer>();	//保存各省的死亡人数
    
	public String addIp = "\\s*\\S+ 新增 感染患者 \\d+人\\s*";
        public String addSp = "\\s*\\S+ 新增 疑似患者 \\d+人\\s*";
        public String inflowIp = "\\s*\\S+ 感染患者 流入 \\S+ \\d+人\\s*";
        public String inflowSp = "\\s*\\S+ 疑似患者 流入 \\S+ \\d+人\\s*";
        public String addDead = "\\s*\\S+ 死亡 \\d+人\\s*";
        public String addCure = "\\s*\\S+ 治愈 \\d+人\\s*";
        public String spToIp = "\\s*\\S+ 疑似患者 确诊感染 \\d+人\\s*";
        public String reduceSp = "\\s*\\S+ 排除 疑似患者 \\d+人\\s*";
	
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");	//设定日期格式
	Date d = new Date(System.currentTimeMillis());
	public String date = dateFormat.format(d);
  • inspectParameter(String [] argsStr)方法

inspectParameter(String [] argsStr)方法可对命令行得参数进行检测,若参数合法则返回true,不合法则返回false.

    public boolean inspectParameter(String [] argsStr) {
		int j;
		args = argsStr;
		if(args.length == 0) {
			System.out.print("No parameters entered.");
			return false;
		}
		if(!argsStr[0].equals("list")) {
			System.out.println("Command line format error.");
			return false;
		}
		for(j = 1;j < argsStr.length;j++) {
			switch(argsStr[j]) {
				case "-log":
					j = inspectLogPath(++j);
					if(j == -1) {
						System.out.println("Command line format error.('-log'parameter)");
						return false;
					}
					else{
						logPath = argsStr[j];
						break;
					}
				case "-date":
					j = inspectDate(++j);
					if(j == -1) {
						System.out.println("Command line format error.('-date'parameter)");
						return false;
					}
					else{
						dateStr = args[j];
						break;
					}
				case "-out":
					j = inspectOutPath(++j);
					if(j == -1) {
						System.out.println("Command line format error.('-outputFile'parameter)");
						return false;
					}
					else{
						outPath = argsStr[j];
						break;
					}
				case "-type":
					j = inspectType(++j);
					if(j == -1) {
						System.out.println("Command line format error.('-type'parameter)");
						return false;
					}
					else
						break;
				case "-province":
					j = inspectProvince(++j); 
					if(j == -1) {
						System.out.println("Command line format error.('-province'parameter)");
						return false;
					}
					else  
						break;
				 default:
					 System.out.println("Unknown error.");
					 return false;
			}
			
		}
		if (types.isEmpty()) {
            types.add("ip");
            types.add("sp");
            types.add("cure");
            types.add("dead");
        }
		return true;
	}`
  • execLog()方法
    调用execLog()方法可以对从参数中获取得路径下的日志文件进行处理,并根据参数情况来保存数据及输出指定文件
public void execLog() throws Exception{
		File f = new File(logPath);
		String[] logFiles = f.list();
		int l = logFiles.length;
		List<String> legalFiles = new ArrayList<String>();
		for(int i = 0;i < l;i++) {
			String  fileDate = logFiles[i].substring(0, 10);
			String suffix = logFiles[i].substring(logFiles[i].lastIndexOf(".") + 1);
			if(suffix.matches("txt") && dateStr.compareTo(fileDate) >=0)
				legalFiles.add(logFiles[i]);
		}
		l = legalFiles.size();
		if(l == 0)
			throw new IllegalException("Error, no legal log file exists in the log directory");
		logFiles = new String[l];
		legalFiles.toArray(logFiles);
		Arrays.sort(logFiles);
		for(int i = 0;i < l;i++) {
			execFile(logPath + "/" + logFiles[i]);
		}
		int ipSum = 0;
		int spSum = 0;
		int cureSum = 0;
		int deadSum = 0;
		for(Integer i : ip.values())
			ipSum += i;
		ip.put("全国", ipSum);
		for(Integer i : sp.values())
			spSum += i;
		sp.put("全国", spSum);
		for(Integer i : cure.values())
			cureSum += i;
		cure.put("全国", cureSum);
		for(Integer i : dead.values())
			deadSum += i;
		dead.put("全国", deadSum);
		 FileOutputStream outFile = new FileOutputStream(outPath);
	        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outFile, "utf-8"));
	        if (typeIsExist) {
	            if (!provinceIsExist) {
	                List<String> list = new ArrayList<String>();
	                int size = provinceStr.length;
	                for (int i = 0; i < size; i++) {
	                    if (ip.get(provinceStr[i]) == 0 && sp.get(provinceStr[i]) == 0
	                            && cure.get(provinceStr[i]) == 0 && dead.get(provinceStr[i]) == 0)
	                        continue;
	                    else
	                        list.add(provinceStr[i]);
	                }
	                outputFile(writer, list);
	            }
	            else {
	                outputFile(writer, provinces);
	            }
	        }
	      else {
	            if (provinceIsExist) {
	                for (String province : provinces) {
	                    writer.write(province + " 感染患者" + ip.get(province) + "人 疑似患者" + sp.get(province) + "人 治愈"
	                            + cure.get(province) + "人 死亡" + dead.get(province) + "人\n");
	                }

	            } 
	            else {
	                Integer[] ipProvincesAmount = new Integer[ip.size()];
	                ip.values().toArray(ipProvincesAmount);
	                Integer[] spProvincesAmount = new Integer[sp.size()];
	                sp.values().toArray(spProvincesAmount);
	                Integer[] cureProvincesAmount = new Integer[cure.size()];
	                cure.values().toArray(cureProvincesAmount);
	                Integer[] deadProvincesAmount = new Integer[dead.size()];
	                dead.values().toArray(deadProvincesAmount);
	                int size = provinceStr.length;
	                for (int i = 0; i < size; i++) {
	                    if (ipProvincesAmount[i] == 0 && spProvincesAmount[i] == 0 && cureProvincesAmount[i] == 0
	                            && deadProvincesAmount[i] == 0)
	                        continue;
	                    else
	                        writer.write(
	                                provinceStr[i] + " 感染患者" + ipProvincesAmount[i] + "人 疑似患者" + spProvincesAmount[i]
	                                        + "人 治愈" + cureProvincesAmount[i] + "人 死亡" + deadProvincesAmount[i] + "人\n");
	                }

	            }
	        }
	        writer.write("//该文档并非真实数据,仅供测试使用");
	        writer.close();
	}

六、单元测试

1
2
3
4
5
6

七、单元测试覆盖率优化和性能测试

l
xn

八、代码规范

详见Github仓库:codestyle.md

九、心路历程与收获

总的说来,一开始看到题目还是感觉啥也不懂,不知道到底要写个什么程序。但是反复阅读再加上和同学讨论后,大概明白大概要完成什么样的一个程序,感觉和Linux课写的脚本作业有点像,相比会复杂好多。比起看一遍就想到思路然后很快就完成的大佬,我只能扣666了。虽然跌跌撞撞,中途也快要面临崩溃,总归还是写完。不得不说deadline是第一生产力作业得早点开始写,不然真的赶不过来。通过这次作业我也学到了很多知识,比如GitHub desktop的使用,单元测试等,此外还复习了Java的相关知识,又是收获满满身心疲惫的一次作业。希望自己早日养成良好学习习惯,不再咸鱼。 bqb
deadline

十、技术路线相关的五个仓库

1.spring-projects/spring-loaded:spring开源的一个热替换插件,运行时监听class文件的变更并执行transform。
GitHub:https://github.com/spring-projects/spring-loaded

2.biezhi/blade:一款轻量级、高性能、简洁优雅的MVC框架。
GitHub:https://github.com/lets-blade/blade

3.spring-boot(Star:26k)
Github:https://github.com/spring-projects/spring-boot

4.基于SSM框架的前后端分离设计完整仿天猫网站服务器端源码。
Github:https://github.com/Liweimin0512/MMall_JAVA

5.mall学习教程,架构、业务、技术要点全方位解析。
Github:https://github.com/macrozheng/mall-learning

posted @ 2020-02-21 03:12  Wzzzq  阅读(187)  评论(2编辑  收藏  举报