寒假作业(2/2)
这个作业属于哪个课程 | 班级链接 |
---|---|
这个作业要求在哪里 | 寒假作业(2/2) |
这个作业的目标 | 学习基础Git命令、Github Desktop使用,为团队合作做准备 |
作业正文 | 见下文 |
其他参考文献 | 百度、简书、CDNS、本次助教发的作业引导 |
1.Github仓库地址
2.PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 120 |
Estimate | 估计这个任务需要多少时间 | 15 | 15 |
Development | 开发 | 120 | 1000 |
Analysis | 需求分析 (包括学习新技术) | 600 | 1000 |
Design Spec | 生成设计文档 | 120 | 120 |
Design Review | 设计复审 | 120 | 150 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 120 | 100 |
Design | 具体设计 | 120 | 80 |
Coding | 具体编码 | 1000 | 1000 |
Code Review | 代码复审 | 240 | 200 |
Test | 测试(自我测试,修改代码,提交修改) | 150 | 180 |
Reporting | 报告 | 120 | 150 |
Test Report | 测试报告 | 60 | 45 |
Size Measurement | 计算工作量 | 20 | 15 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 120 | 100 |
合计 | 1945 | 4275 |
3.解题思路
一开始看到这个项目的时候一脸懵,命令行我知道,Java也知道,可是这两个是怎么联系在一起的我一点都不了解。后来在询问万能的百度后
得到了答案,关键就在main()函数的args参数上,可是对于解题思路还是没有头绪。然后感谢衡与墨助教的第二次作业引导提示,还有纪华裕
助教的Github的使用,给了我很大帮助。我也看了基本所有同学的博客,然后有了一个大致的思路。
这个就是最开始代码前的思路:
当然在写的过程中会渐渐细化并修改,第4点在说
4.设计实现过程
- 模块结构图
- 流程图
从结构流程中可以看出java文件共分为三大类。
- class InfectStatistic
- class CmdHandle
- class FileHandle
InfectStatistic类中只有一个主函数用来运行程序,没有什么好说的,主要讲讲命令处理和文件处理两大类,CmdHandle里的主要函数就是一个GetCmdParam()函数,
用来得到命令行参数,分别是-log,-out,-data,-type,-province对应的参数,logparam//查找的log目录路径,outparam//输出的文件,dataparam//日期之前的
时间都是要处理的,typeparam和province按要求都是数组。FileHandle下有三个主要行数,文件读取ReadFile,那么它是怎么和CmdHandle类联系在一起的呢?就靠
参数logparam和dataparam就能做到读文件,读的文件要进行处理,先正则匹配,这就是DataProcessing函数,处理的数据要输出,输出文件又需要输出路径outparam。
到目前为止,如果没有要求-province,-type命令那么输出有个outparam就可以了,也就是只完成**list -log "..." -out "..." **的基本测试就不需要province
和type的参数,当然前面读文件的dataparam也不需要。因为我有完成所有命令所有还用到另两个参数,因为整个工程函数比较少,没有分很细。
5.代码说明
- CmdHandle的主要函数GetCmdParam():(以下所有代码只贴主要代码)
for(int i=0;i<command.length;i++) {
if (command[i].equals("-log")) {
logparam=command[i+1];
}
else if(command[i].equals("-out")) {
outparam=command[i+1];
}
else if (command[i].equals("-date")) {
dateparam=command[i+1];
}
else if (command[i].equals("-type")) {
for(int j=i+1;j<command.length;j++){
if(command[j].startsWith("-"))
break;
else
typeparam.add(command[j]);
}
}
else if (command[i].equals("-province")) {
for(int j=i+1;j<command.length;j++){
if(command[j].startsWith("-"))
break;
else
provinceparam.add(command[j]);
}
}
}
用一个for循环就能得到一条完整命令的所有参数,各自在各自的String和ArrayList中储存
- ReadFile主要代码:
for (int i = 0; i <= stopPoint; i++) {
String Filename = FilePath + "\\" + FileNames.get(i);
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(Filename), "UTF-8"));
String line = "";
while ((line = br.readLine()) != null) {
if (!line.startsWith("//"))
DataProcessing(line);
}
}
读到line中,读一行DataProcessing函数处理一行,边读边处理,读日期前所有文件所有行
- DataProcessing主要代码
String pattern1 = "(\\S+) 新增 感染患者 (\\d+)人";
String pattern2 = "(\\S+) 新增 疑似患者 (\\d+)人";
String pattern3 = "(\\S+) 治愈 (\\d+)人";
String pattern4 = "(\\S+) 死亡 (\\d+)人";
String pattern5 = "(\\S+) 感染患者 流入 (\\S+) (\\d+)人";
String pattern6 = "(\\S+) 疑似患者 流入 (\\S+) (\\d+)人";
String pattern7 = "(\\S+) 疑似患者 确诊感染 (\\d+)人";
String pattern8 = "(\\S+) 排除 疑似患者 (\\d+)人";
boolean isMatch1 = Pattern.matches(pattern1, line);
boolean isMatch2 = Pattern.matches(pattern2, line);
boolean isMatch3 = Pattern.matches(pattern3, line);
boolean isMatch4 = Pattern.matches(pattern4, line);
boolean isMatch5 = Pattern.matches(pattern5, line);
boolean isMatch6 = Pattern.matches(pattern6, line);
boolean isMatch7 = Pattern.matches(pattern7, line);
boolean isMatch8 = Pattern.matches(pattern8, line);
if(isMatch1) //新增 感染患者处理
DealIP(line);
else if(isMatch2) //新增 疑似患者处理
DealSP(line) ;
else if(isMatch3) //新增 治愈患者处理
DealCure(line);
else if(isMatch4) //新增 死亡患者处理
DealDead(line);
else if(isMatch5) //感染患者 流入处理
FlowIP(line);
else if(isMatch6) //疑似患者 流入处理
FlowSP(line);
else if(isMatch7) //疑似患者 确诊感染处理
TurnSPtoIP(line);
else if(isMatch8) //排除 疑似患者处理
RemoveSP(line);
主要就是正则匹配,line参数每次匹配true,就交给对应的处理函数处理
- 处理函数如下
public void DealIP(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int n = Integer.valueOf(str[3].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
InfectedPatients[i]+=n;//该省份感染患者人数增加
AllIP+=n;//全国感染患者人数增加
IsProvince[i] = true;
break;
}
}
}
public void DealSP(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int n = Integer.valueOf(str[3].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
SuspectedPatients[i]+=n;//该省份感染患者人数增加
AllSP+=n;//全国感染患者人数增加
IsProvince[i] = true;
break;
}
}
}
public void DealCure(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int n = Integer.valueOf(str[2].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
InfectedPatients[i]-=n;//该省份感染患者人数减少
CurePatients[i]+=n;//该省份治愈患者人数增加
AllIP-=n;//全国感染患者人数减少
AllCURE+=n;
IsProvince[i] = true;
break;
}
}
}
public void DealDead(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int n = Integer.valueOf(str[2].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
InfectedPatients[i]-=n;//该省份感染患者人数减少
DeadPatients[i]+=n;//该省份治愈患者人数增加
AllIP-=n;//全国感染患者人数减少
AllDEAD+=n;
IsProvince[i] = true;
break;
}
}
}
public void FlowIP(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int flag2=0;
int n = Integer.valueOf(str[4].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
InfectedPatients[i]-=n;//该省份感染患者人数减少
IsProvince[i] = true;
flag2+=1;
//break;
}
if(str[3].equals(provinces[i])){
InfectedPatients[i]+=n;//该省份感染患者人数增加
IsProvince[i] = true;
flag2+=1;
//break;
}
if(flag2==2) break;
}
}
public void FlowSP(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int flag3=0;
int n = Integer.valueOf(str[4].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
SuspectedPatients[i]-=n;//该省份疑似患者人数减少
IsProvince[i] = true;
flag3+=1;
//break;
}
if(str[3].equals(provinces[i])){
SuspectedPatients[i]+=n;//该省份疑似患者人数增加
IsProvince[i] = true;
//break;
flag3+=1;
}
if(flag3==2) break;
}
}
public void TurnSPtoIP(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int n = Integer.valueOf(str[3].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
SuspectedPatients[i]-=n;//该省份疑似患者人数减少
InfectedPatients[i]+=n;//该省份感染患者人数增加
AllSP-=n;
AllIP+=n;
IsProvince[i] = true;
break;
}
}
}
public void RemoveSP(String line){
String[] str = line.split(" "); //将字符串以空格分割为多个字符串
int n = Integer.valueOf(str[3].replace("人", ""));//将人前的数字从字符串类型转化为int类型
for(int i = 0; i < provinces.length; i++){
if(str[0].equals(provinces[i])){
SuspectedPatients[i]-=n;//该省份疑似患者人数减少
AllSP-=n;
IsProvince[i] = true;
break;
}
}
值得一提的是在(\S+) 感染患者 流入 (\S+) (\d+)人的处理函数中我犯了个错误,原本两个if只会运行其中一种情况就会退出,
也就是说只会两个省只会有一个有数据处理,后来我加了个flag2变量当它等于2时才退出循环
- 最后是WriteFile的代码
BufferedWriter fileWritter= null;
fileWritter= new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF-8")));
if((provinceparam.size() == 0)&&(typeparam.size() == 0)){
String result="全国" + " " + "感染患者" + AllIP + "人" + " " + "疑似患者" + AllSP + "人" + " " + "治愈" + AllCURE + "人" + " " + "死亡" + AllDEAD + "人" + "\n";
fileWritter.write(result);
for (int i = 0; i < 31; i++) {
if (IsProvince[i]) {
String st =provinces[i] + " " + "感染患者" + InfectedPatients[i] + "人" + " " + "疑似患者" + SuspectedPatients[i] + "人" + " " + "治愈" + CurePatients[i] + "人" + " " + "死亡" + DeadPatients[i] + "人" + "\n";
fileWritter.write(st);
}
}
}
if((provinceparam.size() > 0)&&(typeparam.size() == 0)){
for(int i=0;i<provinceparam.size();i++){
if(provinceparam.get(i).equals("全国")){
String result="全国" + " " + "感染患者" + AllIP + "人" + " " + "疑似患者" + AllSP + "人" + " " + "治愈" + AllCURE + "人" + " " + "死亡" + AllDEAD + "人" + "\n";
fileWritter.write(result);
}
}
for(int j=0;j<31;j++){
for(int i=0;i<provinceparam.size();i++){
if(provinces[j].equals(provinceparam.get(i))){
String st =provinces[j] +" " + "感染患者" + InfectedPatients[j] + "人" + " " + "疑似患者" + SuspectedPatients[j] + "人" + " " + "治愈" + CurePatients[j] + "人" + " " + "死亡" + DeadPatients[j] + "人" + "\n";
fileWritter.write(st);
}
}
}
}
if((provinceparam.size() == 0)&&(typeparam.size() > 0)){
String result="全国"+" ";
for (int i = 0; i < typeparam.size(); i++) {
if (typeparam.get(i).equals("ip")) {
result +="感染患者" + AllIP + "人 ";
}
if (typeparam.get(i).equals("sp")) {
result +="疑似患者" + AllSP + "人 ";
}
if (typeparam.get(i).equals("cure")) {
result +="治愈" + AllCURE + "人 ";
}
if (typeparam.get(i).equals("dead")) {
result +="死亡" + AllDEAD + "人 ";
}
}
result+="\n";
fileWritter.write(result);
for (int i = 0; i < 31; i++) {
if (IsProvince[i]) {
String st =provinces[i]+" ";
for (int j = 0; j< typeparam.size(); j++) {
if (typeparam.get(j).equals("ip")) {
st +="感染患者" + InfectedPatients[i] + "人 ";
}
if (typeparam.get(j).equals("sp")) {
st +="疑似患者" + SuspectedPatients[i] + "人 ";
}
if (typeparam.get(j).equals("cure")) {
st +="治愈" + CurePatients[i] + "人 ";
}
if (typeparam.get(j).equals("dead")) {
st +="死亡" + DeadPatients[i] + "人 ";
}
}
st +="\n";
fileWritter.write(st);
}
}
}
if((provinceparam.size() > 0)&&(typeparam.size() > 0)){
for(int i=0;i<provinceparam.size();i++){
if(provinceparam.get(i).equals("全国")){
String result="全国" + " ";
for (int j = 0; j < typeparam.size(); j++) {
if (typeparam.get(j).equals("ip")) {
result +="感染患者" + AllIP + "人 ";
}
if (typeparam.get(j).equals("sp")) {
result +="疑似患者" + AllSP + "人 ";
}
if (typeparam.get(j).equals("cure")) {
result +="治愈" + AllCURE + "人 ";
}
if (typeparam.get(j).equals("dead")) {
result +="死亡" + AllDEAD + "人 ";
}
}
result+="\n";
fileWritter.write(result);
}
}
for(int j=0;j<31;j++){
for(int i=0;i<provinceparam.size();i++){
if(provinces[j].equals(provinceparam.get(i))){
String st =provinces[j] +" ";
for (int z = 0; z< typeparam.size(); z++) {
if (typeparam.get(z).equals("ip")) {
st +="感染患者" + InfectedPatients[j] + "人 ";
}
if (typeparam.get(z).equals("sp")) {
st +="疑似患者" + SuspectedPatients[j] + "人 ";
}
if (typeparam.get(z).equals("cure")) {
st +="治愈" + CurePatients[j] + "人 ";
}
if (typeparam.get(z).equals("dead")) {
st +="死亡" + DeadPatients[j] + "人 ";
}
}
st +="\n";
fileWritter.write(st);
}
}
}
}
fileWritter.write("//该文档并非真实数据,仅供测试使用\n");
fileWritter.flush();
fileWritter.close();
很长,我也写的眼花了,其实就是new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), Charset.forName("UTF-8")))
使输出文本也是UTF-8的形式,然后四个if对无-province无-type,有-province无-type,无-province有-type,有-province有-type分别进行处理,
最后一种有3重循环我也绕了好久。
6.单元测试截图和描述
不多说直接贴代码,都在注解里了
@Test
public void text1() {//有log,out,date "2020-01-22"
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-22"};
InfectStatistic.main(str);
}
@Test
public void text2() {//有log,out,date "2020-01-23"
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-23"};
InfectStatistic.main(str);
}
@Test
public void text3() {//有log,out,date "2020-01-27"
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut4.txt","-date","2020-01-27"};
InfectStatistic.main(str);
}
@Test
public void text4() {//有log,out
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut4.txt"};
InfectStatistic.main(str);
}
@Test
public void text5() {//有log,out,date,province"福建","全国"
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-23","-province","福建","全国"};
InfectStatistic.main(str);
}
@Test
public void text6() {//有log,out,date,province 3个打乱顺序的参数"湖北","福建","全国"
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-23","-province","湖北","福建","全国"};
InfectStatistic.main(str);
}
@Test
public void text7() {//有log,out,date,type 参数 ip
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-23","-type","ip"};
InfectStatistic.main(str);
}
@Test
public void text8() {//有log,out,date,type 参数ip,cure
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-23","-type","ip","cure"};
InfectStatistic.main(str);
}
@Test
public void text9() {//有log,out,date,type 参数sp,province "福建""全国"
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-23","-type","sp","-province","福建","全国"};
InfectStatistic.main(str);
}
@Test
public void text10() {//有log,out,date,type 参数 ip sp cure,province "福建""全国" "湖北"
String[] str={"list","-log","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\log","-out","C:\\Users\\asus\\IdeaProjects\\InfectStatistic-main\\221701408\\result\\ListOut1.txt","-date","2020-01-23","-type","ip","sp","cure","-province","福建","全国","湖北"};
InfectStatistic.main(str);
}
- text1()运行结果//有log,out,date "2020-01-22"
- text2()运行结果//有log,out,date "2020-01-23"
- text3()运行结果//有log,out,date "2020-01-27"
- text4()运行结果//有log,out
- text5()运行结果//有log,out,date,province"福建","全国"
- text6()运行结果//有log,out,date,province 3个打乱顺序的参数"湖北","福建","全国"
- text7()运行结果//有log,out,date,type 参数 ip
- text8()运行结果//有log,out,date,type 参数ip,cure
- text9()运行结果//有log,out,date,type 参数sp,province "福建""全国"
- text10()运行结果//有log,out,date,type 参数 ip sp cure,province "福建""全国" "湖北"
7.单元测试覆盖率优化和性能测试
- 覆盖率如图
- 性能测试,图一片空白,我下了插件,下了软件,不知道为什么在IDEA中不能设置.exe的包
8.git仓库链接、代码规范链接
9.心路历程和收获
打算开始项目时我非常无措,无从下手。渐渐到截止日期,就开始变得焦虑,好几天没睡好,一睡醒就是代码代码,每天坐在电脑前哪都没去,可是一到晚上就知道自己又干坐了一天,
一直都在忙着配置,查错,各种安装包,插件,感觉一事无成,代码一直没敲。第一次接触git,github,和IDEA从安装到测试到使用就一直出问题,后来发现似乎github desktop桌面
版是可以不用下的,只需要一个github账号和IDEA就可以完成本次任务。而我光是各种安装配置就弄了两天,看起来是枯坐,不过如果不是之前前置工作我后面的也不会进行的还算顺
利。这也让我发现一个问题,各种软件的安装和使用是基本的能力,而我因为在学校遇到安装问题的时候因为有同学的帮助而忽略了自己缺少这部分能力,经过这个项目,我对git,github,
IDEA有了大致的了解,能做到基本的使用,还锻炼了独自上网解决问题的能力。
同时巩固了Java快要遗忘的部分内容,特别是输入输出函数。
正因为之前的许多困难,项目完成时才显得可贵。完成后我的紧绷心情一下放松了。
10.技术路线图相关的5个仓库
- 码出高效_阿里巴巴Java开发手册
里面有各种Java的编程规范、异常日志、MySQL规约、工程规约、安全规约。 - 27天成为Java大神
里面有27个文件夹,27天,包含代码,图片,文本,视频,据说27天就能成为大神。 - Java学习+面试指南
一份涵盖大部分Java程序员所需要掌握的核心知识。 - javascript
Note: this guide assumes you are using Babel, and requires that you use babel-preset-airbnb or the equivalent. It also assumes you are installing shims/polyfills in your app, with airbnb-browser-shims or the equivalent. - Kaitai Struct
Kaitai Struct: declarative language to generate binary data parsers in C++ / C# / Go / Java / JavaScript / Lua / Perl / PHP / Python / Ruby