#做业描述 | 问题 | 内容 | | :-----| :----| | 这个做业属于哪一个课程 | 2020春丨W班| |这个做业要求在哪里|寒假做业(2/2)| |这个做业的目标|完成疫情统计的程序以及博客| |做业正文|寒假做业(2/2)——疫情统计| |其余参考文献|...| #1.Github仓库地址 本项目使用Java开发 做业仓库地址:疫情统计html
学长因为第一次使用GitHub不是很熟悉,刚开始的时候我编写的时候新建了一个新的仓库来编写,任何commit,push操做都在那个仓库完成,最后要pr的时候发现不能提交,才知道是本身理解错了,因此 提交的那份做业里面没有commit记录,若是容许的话我这里贴一份旧的仓库连接,须要看commit记录的话能够看这个仓库的记录,两份的代码是同样的。 旧仓库:有commit记录的库 #2.PSP表格 | PSP2.1 | Personal Software Process Stages | 预估耗时(分钟)| 实际耗时(分钟) | :-----| :----| :-----| :----| :-----| :---- | | Planning | 计划 | 30 | 40 | Estimate | 估计这个任务须要多少时间 | 720 | 900 | Development | 开发 | 600 | 720 | Analysis | 需求分析(包括学习新技术) | 60 | 120 | Design Spec | 生成设计文档 | 30 | 30 | Design Review | 设计复审 | 30 | 60 | Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30 | 30 | Design | 具体设计 | 60 | 120 | Coding | 具体编码 | 480 | 540 | Code Review | 代码复审 | 60 | 50 | Test | 测试(自我测试,修改代码,提交修改) | 120 | 180 | Reporting | 报告 | 120 | 150 | Test Report | 测试报告 | 60 | 120 | Size Measurement | 计算工做量 | 30 | 10 | Postmortem & Process Improvement Plan | 过后总结, 并提出过程改进计划 | 30 | 30 | 合计 | | 2460 | 3100 #3.解题思路 ###1.命令行输入命令的接收与保存 1.刚看到题目的时候,想的比较简单,使用" "空格符号来分割传入的命令便可,可是后面仔细一想,有的命令有多个参数仅仅依靠空格符并不能很好的实现,最后决定先依靠"-"符号分割,分割结束后依靠" "再次分割处理获得传入的命令。 2.为了保存命令,声明了一个命令类(class command)该类用于保存命令跟命令后带的参数,同时也进行命令跟命令参数的格式检查。 ###2.日志文件的读取 1.判断日志文件路径是否正确。 2.声明一个省份类对象数组(class province)用于保存各个省份的数据。 3.根据题目要求日志文件内容的格式仅有8种。java
<省> 新增 感染患者 n人 <省> 新增 疑似患者 n人 <省1> 感染患者 流入 <省2> n人 <省1> 疑似患者 流入 <省2> n人 <省> 死亡 n人 <省> 治愈 n人 <省> 疑似患者 确诊感染 n人 <省> 排除 疑似患者 n人git
便考虑到使用正则表达式去匹配每一行的数据,若命中跳转分支去抓取省份名称跟人数进行处理。 4.按照正则表达式抓取的数据修改province数组中的相应位置的数据。 ###3.结果的输出 1.判断结果输出路径是否正确 2.查看是否有特定输出要求(-province,-type是否的指定) 3.输出相应结果到指定的文件中 在画这个图片的时候,发现了判断输入/输出路径最好应该在判断命令格式跟命令是一块儿判断,这样若是有误就能够直接结束程序,不在浪费系统资源,如有修改将放在下面代码优化部分。 ###4.设计实现过程 1.命令类(class command)程序员
//命令类 //list:判断是否输入-list //log:判断是否输入-log //out:判断是否输入-out //date:判断是否输入-date //type:判断是否输入-type //province:判断是否输入-province //dateContent:-date命令后带参数 //logContent:-log命令后带参数 //outContent:-out命令后带参数 //provinceContent:-province后带参数 //typeContent:-type后带参数 //command:输入的命令字符串数组 class Command{ private Boolean list=false; private Boolean log=false; private Boolean out=false; private Boolean date=false; private Boolean type=false; private Boolean province=false; private String dateContent; private String logContent; private String outContent; private List<String> provinceContent = new ArrayList<String>(); private List<String> typeContent = new ArrayList<String>(); private List<String> command = new ArrayList<String>(); ...... }
2.省份类github
//省份类 用于存储各个全国和各个省份的各类数据 //代码中开辟一个province数组,第0位存放全国,其他省份按排序一次存放 //name:省份的名称 //ip:感染患者数量 //sp:疑似患者数量 //cure:治愈患者数量 //dead:死亡患者数量 //appear:用来判断是否在日志文件中出现该省份 class province { private String name; private int ip; private int sp; private int cure; private int dead; private boolean appear; .... }
3.文件操做-读类正则表达式
//文件操做类-读文件 //path:日志文件的路径,-log后带的参数 //files:该路径下的说有文件路径(绝对路径) //filesName:该路径下全部文件的名称,用于判断输入的日期是否超出范围(仅名称不带后缀) //file:文件路径打开的文件夹 //tempList:该路径下的全部文件 //provinceList:省份数组 //templates:用于匹配日志文件内容的正则表达式模板 //maxDate:该路径下的日志文件的最大日期 //minDate:该路径下的日志文件的最小日期 class readFile{ String path; ArrayList<String> files; ArrayList<String> filesName; File file; File[] tempList; province [] provinceList; String [] templates = { "(\\S+) 新增 感染患者 (\\d+)人","(\\S+) 新增 疑似患者 (\\d+)人","(\\S+) 感染患者 流入 (\\S+) (\\d+)人", "(\\S+) 疑似患者 流入 (\\S+) (\\d+)人","(\\S+) 死亡 (\\d+)人","(\\S+) 治愈 (\\d+)人", "(\\S+) 疑似患者 确诊感染 (\\d+)人", "(\\S+) 排除 疑似患者 (\\d+)人" }; String maxDate; String minDate; ... }
4.文件操做-写类编程
//文件操做类-写文件 //provinceList:全国和各个省份的数据统计数组 //isProvince:命令行是否接收-province命令 若是有 isProvince=true反之false //provinceContent:-province命令后带的参数 //isType:命令行是否接收-type命令 值同isProvince //typeContent:-type命令后带的参数 //file:输出结果文件 class writeFile { private province [] provinceList; private boolean isProvince; private List<String> provinceContent; private boolean isType; private List<String> typeContent; private File file; ... }
###5.代码说明 看了下本身的代码,好像发现没什么值得展现的,都是一些比较日常的代码,也没有难以理解,下面就解释一下一些稍微难以理解的代码(为了偷懒写的代码) 代码的具体解释写在来各个代码块的开头的注释和代码旁边的注释中数组
//判单读取日志文件数量 //传入参数:日期 如:2020-01-22 //返回值:false 或 true //path:-date命令后面带的日期 //path有两种取值:1.正常日期 ,输入-date后带的符合规范的日期。 // 2. “all” 字符串,未输入-date命令或者输入-date命令后未指定具体日期时 // 为了偷懒默认日期就为all,仅当有输入-date命名且输入指定日期后才更新 public boolean readLog(String path) { if(path.equals("all")) //若是path是all直接读取到maxDate日期为止 { readLogFile(maxDate); return true; } else { if(path.compareTo(maxDate)>0||path.compareTo(minDate)<0)//判断输入的日期是否在日志文件的 { //范围中 return false; } else { readLogFile(path); return true; } } }
//输入结果到文件方法 //没有想到什么好的解决办法,就把每种状况都列了出来 //isProvince=true这表明输入了-province命令,反之没有 //isType=true这表明输入了-type命令,反之没有 //按题目要求输出有四种不一样的状况 //1.没输入-province命令,没输入-type //2.输入-province命令,没输入-type //3.输入-province命令,输入-type //4.没输入-province命令,输入-type //分别与下面的四个判断对应 //因为嵌套循环较多,若程序性能较差能够考虑修改这方面的代码(虽然我已经想过了) //由于嵌套循环跟判断较多具体代码就不贴了,详细能够看代码,这理解解释下这四个判断的做用 if(isProvince==false&&isType==false){...} if(isProvince==true&&isType==false){...} if(isProvince==true&&isType==true){...} if(isProvince==false&&isType==true){...}
//判断各命令参数是否合法 //输入参数:无 //返回值:true或false //-list必不可少,-date无关紧要 日期格式(yyyy-mm-dd)缺一不可 //-log命名跟后带参数均不可少 //-out命名跟后带参数均不可少 //原本还应该-province后面的参数只能是“全国或各个省份名称”,可是因为偷懒就没写了。 //看做业要求好像测试的时候也不会出现这样的状况,就算出现了代码也能正常运行不会异常终止罢了😂 public boolean isLegal() { if(!list) { System.out.println("-list命令缺失"); return false; } if(date) { String regex = "[0-9]{4}-[0-9]{2}-[0-9]{2}";//这段代码的做用是为了保证必须知足(yyyy-mm-dd)反例:如(2020-1-2)也是错误的 Pattern pattern = Pattern.compile(regex);//为何写它是由于好像java自带的日期格式判断会将上述反例判断为正确,顾添加了一段代码 Matcher m = pattern.matcher(dateContent); boolean dateFlag = m.matches(); if (!dateFlag) { System.out.println("日期格式错误"); return false;//日期格式错误 例如:2020-1-3(正确为2020-01-03) } DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); formatter.setLenient(false); try{ formatter.parse(dateContent); }catch(Exception e){ System.out.println("日期格式错误!"); return false;//日期格式错误 例如:2a20-01-03(出现非数字字符) } } if(log)//输入了-log命令 { if(logContent==null)//logContent为-log命令后面后带的参数 { System.out.println("-log命名参数缺失!"); return false;//输入-log命令 却未输入参数 } } else { System.out.println("缺失-log命令!"); return false;//缺乏-log命令 } if(out) { if(outContent==null) { System.out.println("-out命令参数缺失!"); return false;//输入-out命令 却未输入参数 } } else { System.out.println("缺失-out命令!"); return false;//缺失-out命令 } if(type) { if(typeContent==null) { System.out.println("-typy命令参数缺失!"); return false;//输入-type 命令 却不输入参数 } else { for(int i=0;i<typeContent.size();i++) { if(!typeContent.get(i).equals("sp")&&!typeContent.get(i).equals("ip") &&!typeContent.get(i).equals("cure")&&!typeContent.get(i).equals("dead")) { System.out.println("-type命令参数错误!"); return false;//type的参数不是(ip sp cure dead四种之一) } } } } if(province) { if(provinceContent==null) { return false;//输入 -province命令却不输入参数 } } return true; }
###6.单元测试截图和描述 测试日志文件日期: 测试日志文件内容:
测试结果以下: (1)输入命名 list -log C:\log\ -out C:\result\ListOut1.txt -date 2020-01-22
(2)输入命令 list -log C:\log\ -out C:\result\ListOut2.txt -date 2020-01-22 -province 福建 河北
(3)输入命令 list -log C:\log\ -out C:\result\ListOut7.txt -date 2020-01-23 -type cure dead ip -province 全国 浙江 福建
(4)输入命令 list -log C:\log\ -out C:\result\ListOut.txt (无-date命令,统计所有结果)
(5) 输入命令 list -log C:\log\ -out C:\result\ListOut.txt -date 2020-03-22 (日期超出范围)
(6) 输入命令 list -log C:\log\ -out C:\result\ListOut.txt -date 2020-01-a2 (日期格式错误)
(7) 输入命令 list -log C:\log\ -out C:\result\ListOut.txt -type aa (type命令参数错误)
(8) 输入命令 list -log D:\log\ -out C:\result\ListOut.txt (日志文件路径错误,电脑不存在D盘)
(9) 输入命令 list -log C:\log\ -out D:\result\ListOut.txt (输出文件路径错误,电脑不存在D盘)
(10) 输入命令 list -out D:\result\ListOut.txt (缺失-log命令)
(11) 输入命令 list -log -out D:\result\ListOut.txt (缺失-log命令后带参数)
###7.单元测试覆盖优化和性能测试 单元测试覆盖率代码: 测试命令:list -log C:\log -out C:\result\ListOut7.txt -date 2020-01-27 结果:
分析: 1.Command覆盖率较低是因为命令并未彻底输入 未输入-province等命令致使分支并未跑到,同时其中还包含命令正确性判断模块。 2.writeFile类覆盖率低但接近预期值,这是因为输出模块为四个判断分支,只选取其中一段分支运行故接近25% 性能测试结果:
分析: 1.输出模块中for循环嵌套较多,性能较差。 2.分支判断过多致使一些分支执行的次数较少。 3.性能优化暂无办法,写的时候就已经考虑过了。 ###8.代码规范 个人代码规范 ###9.心路历程与收获 1.经过此次做业,了解到了Java的单元测试跟单元测试覆盖率还有性能测试,这是我认为经过此次做业最大的收获,以前写代码都是写完便可并无去考虑这些。 2.做业也让我从新复习了一遍Java的各类语法跟使用,对java有了更深的了解。 3.此次做业也让咱们规范了本身的编程风格,这是在以前的日子从未有过的致使本身写出来的代码有时候本身都看不懂,经过代码规范让本身的代码更加的易懂。 4.同时发现本身过于心急,并无拿到手上并无很是好的进行需求分析,一到手就开始编写,致使不少东西在编写的过程当中改来改去,这一点很是很差之后要认认真真的进行需求分析。 5.学习了GitHub的使用,以前老以为这些东西没什么好的,本身写就是了,用了以后发现真香。 6.认清了本身的位置,对于成为一名合格的程序员还有很长的路要走 ###10.技术路线图相关的5个仓库 | 名称 | 连接 | 简介 | | :-----| :----|:----| | RxJava | RxJava | JAVA的一种异步框架,使用可观测的序列来组成异步的,基于事件的程序的库 | | RxAndroid | RxAndroid | RxAndroid是专供Android平台的RxJava | | Android布局 | Android布局 | 一些Android布局教材跟例子 | | Android学习笔记 | Android学习笔记 | 由国内知名博主编写的Android入门教材 | |《第一行代码》中天气案例 | 《第一行代码》中天气案例| 《第一行代码》中的天气预报的例子加改写 |性能优化