这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/2020SpringW |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/2020SpringW/homework/10281 |
这个作业的目标 | <建立一个用于疫情统计的简易软件> |
作业正文 | 此文章 |
其他参考文献 | github,csdn,google |
1、Github仓库地址
本次软件使用Java语言开发
仓库地址:https://github.com/Notec17/InfectStatistic-main
2、PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30+ | 120 |
Estimate | 估计这个任务需要多少时间 | 30+ | 60 |
Development | 开发 | 120+ | 300 |
Analysis | 需求分析 (包括学习新技术) | 120+ | 240 |
Design Spec | 生成设计文档 | 60+ | 90 |
Design Review | 设计复审 | 30+ | 120 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 30+ | 20 |
Design | 具体设计 | 60+ | 100 |
Coding | 具体编码 | 60+ | 200 |
Code Review | 代码复审 | 30+ | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 120+ | 60 |
Reporting | 报告 | 30+ | 120 |
Test Report | 测试报告 | 30+ | 30 |
Size Measurement | 计算工作量 | 30+ | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30+ | 30 |
合计 | 930+ | 1580 |
3、解题思路
- 3.1 初见
最开始看到题目的时候,头脑里对于使用cmd运行java非常懵,一个是java并不是强项,另一个是我可以说完全没有cmd运行代码的相关项目处理。
于是便开始问一些Java比较拿手的同学以及自己在网上查阅资料进行学习,才开始慢慢理解这次题目要怎么做。比如使用正则表达式写匹配句式等。可以说最开始是只有一个最基本的简单从文本输入读入处理读出的解题思路。在还没正式开始解题时我曾试着使用相关命令模式进行代码的编写,但是由于我对模式的不熟悉导致我写了很多发现代码难以进行下去从而抛弃了该设计。 - 3.2 有关命令行
命令行在我最开始是直接想到用args的参数读入数据,然后存储在一个String数组中遍历一个一个读取出来,比如一个命令-log后面接的就是他的参数。
而-province的多参数则从当前位置开始读字符串,直到读到一个以"-"符号开头的字符串便终止即可获取全部参数。 - 3.3 字符串匹配
这个最开始我是想的最笨的方法,就是直接写对应的句子来进行String的compare,后来看了助教的引导博客才知道可以用正则表达式(在这之前完全忘光了)。 - 3.4 输入与输出
由于使用cmd读入,所以输入方面3.2基本就概括完了,而输出则是通过文件流重定向out直接写到所获得的指定路径文件中,也算是比较简单。 - 3.5 数据的保存
既然要匹配一堆数据,那么自然要想好数据怎么保存,我想的是用各种全局变量来储存,申请很多String数组或者ArrayList亦或是Hashmap,这些都有在代码中体现。
4、设计实现
关于本次的设计,首先我要反思。
最开始我想着是学习命令模式中的各种模式来对代码进行一个良好的构筑,既可以增加代码可读性,又可降低代码重用,优点我个人认为很多,于是我便开始边学习边架构设计,但是由于没有系统性的学习所有设计模式,每个模式都只是看了几个甚至一个简单的例子就开始着手打代码,导致在作业布置两周后还没有什么喜人的进展,从而让我在最后ddl阶段还重新开始设计并架构,github上的commit也十分紧凑,完全没有应该有的计划性与安排。
言归正传,本项目最终的设计还是回归基本,如下图。
我个人也认为这个结构非常不好,修改麻烦,不符合各种设计模式,缺点还可列举一大把。在下次的作业争取使用更好的架构。
5、代码说明
代码比较关键的部分是正则表达式匹配部分和读入写出部分。
- 5.1 正则表达式部分
String smatch1 = "^[\u4e00-\u9fa5]*\s(新增)\s(感染患者)\s(\d+)人?";
String sorigin1 = " 新增 感染患者 |人";
String smatch2 = "^[\u4e00-\u9fa5]*\s(新增)\s(疑似患者)\s(\d+)人?";
String sorigin2 = " 新增 疑似患者 |人";
String smatch3 = "^[\u4e00-\u9fa5]*\s(感染患者)\s(流入)\s[\u4e00-\u9fa5]*\s(\d+)人?";
String sorigin3 = " 感染患者 流入 | |人";
其中的编码代表所有中文,由于是第一次编写正则表达式,所以还没法体现较好的可读性(?)。
- 5.2 读入
ArrayList<String> filePath = GetTxt(log,date);
//GetTxt函数为获取文件内容
for(int i=0;i<filePath.size();i++) {
BufferedReader inBufferedReader=new BufferedReader(new InputStreamReader(new FileInputStream(filePath.get(i)), "UTF-8"));
String es;
while((es=inBufferedReader.readLine())!=null) {
//下略正则表达式匹配代码
- 5.3 写出
此部分代码参考了网上的代码改写,看过别人的博客之后发现有部分人可能跟我参考了相同的代码,简单分析下
通过重定向文件输出流写入从命令中读到-out的参数从而在指定位置生成txt文件写入读到转化成的String内容(符合-date等指令)
public static void PrintTxt(String log,String out,String date,String [] type,String [] province) throws IOException {
File file=new File(out);
if(!file.exists()) {
file.createNewFile();
}
PrintStream ps=new PrintStream(out);
System.setOut(ps);
for(int i=1;i<32;i++)
for(int j=0;j<4;j++) totaltype[0][j]+=totaltype[i][j];
//System.out.println('1');
if(province[0].equals("undefined")){
province = prov.clone();
}
if(type[0].equals("undefined")){
type = typeId.clone();
}
for(int i=0;i<prov.length;i++) {
for(int j=0;j<province.length;j++) if(prov[i].equals(province[j])){
System.out.print(prov[i]+" ");
Integer pronum=(Integer) pmap.get(prov[i]);
int typecnt=0;
for(int k=0;k<4;k++) {
if(type[k].equals("undefined")) typecnt++;
}
for(int k=0;k<4;k++) if((typecnt==4)||(!type[k].equals("undefined"))){
Integer typenum=(Integer) tmap.get(type[k]);
System.out.print(typeName[typenum]+totaltype[pronum][typenum]+" ");
}
System.out.println();
}
}
}
6、单元测试描述
单元测试代码
import org.junit.Test;
import java.io.IOException;
class Test1 {
@Test
void test1() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province"};
InfectStatistic.main(str);
}
@Test
void test2() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province"};
InfectStatistic.main(str);
}
@Test
void test3() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-type","dead"};
InfectStatistic.main(str);
}
@Test
void test4() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-type","cure","dead"};
InfectStatistic.main(str);
}
@Test
void test5() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-province","全国"};
InfectStatistic.main(str);
}
@Test
void test6() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-date","2020-1-22"};
InfectStatistic.main(str);
}
@Test
void test7() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-type","cure","dead","-province","福建"};
InfectStatistic.main(str);
}
@Test
void test8() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-date","2020-1-22","-type","cure","dead","-province","福建"};
InfectStatistic.main(str);
}
@Test
void test9() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-date","2020-1-22","-province","福建"};
InfectStatistic.main(str);
}
@Test
void test10() throws IOException {
String[] str = {"list",
"-log", "E:\codes\ja\src\InfectStatistic\example\log",
"-out", "E:\codes\ja\src\InfectStatistic\example\result\test1.txt -type curu dead -province",
"-date","2020-1-22","-type","cure","dead","-province","全国","福建"};
InfectStatistic.main(str);
}
}
7、单元测试覆盖率与性能
覆盖率
由于网络问题,IDEA一直无法下载JProfiler插件,改用eclipse也不知道相应解决办法,故无法获取具体数值。
8、代码规范链接
https://github.com/Notec17/InfectStatistic-main/blob/master/221701138/codestyle.md
参考了大一时写的C/C++代码规范,总体上规则还是较少,可能是由于本人代码量还不够的原因,还不需要太多规则来限制。
9、此次项目的心路历程
就本次软件开发而言,收获最大的就是:一定别高估自己。
就是因为错误估计了很多地方耗费的时间,导致最后整体框架都破烂不堪,实在是愧疚。对于时间的把握还是没有比较准确的概念,争取在今后的项目中不断进步。
其次让我感觉收获颇丰的地方就是重新过了一遍java并且理解了一些以前不懂的知识点,比如正则表达式的运用。虽然此次代码参考了很多网上的各种代码,但是我个人认为在不断的改写中悟到知识点并且加深理解,其实是非常有价值的。最开始按照各种设计模式的例子进行了架构,学到了很多不需要if也能保证分支的技巧(或者说方式),当时就感觉小有成就感,但是现实终究是残酷的,最后经验不足与能力不足导致整体项目还是跟以前没有什么区别,一样烂(
但是个人学到的能够运用在下次的东西我敢肯定是非常多的,一定是利大于弊的。
阅读构建之法前三章呢,让我想起我在大二读的一本书叫《代码大全》。当时我看代码大全也粗略了解了很多有关软件架构的知识,并且看到了很多生动有趣的例子,比如把编写软件比作造房子,设计图什么的必不可少等。结合构建之法和我之前的认知,软件=程序plus软件工程,即要有足够的coding能力以及足够的管理能力等方面才能够真正成为一名合格的Software Engineer。我想我会找一个时间把构建之法读完,个人认为其中的思想都有可取之处,希望在之后的阅读过程中能够丰富我个人有关软件方面的思想。
10、5个计算机图形学相关仓库
- 10.1 SORT
一个开源的光线追踪项目,属于比较深层次的计算机图形学内容 https://github.com/Notec17/SORT - 10.2 SLProject
一个3D计算及图形的库,包含大量的图形生成相关代码、手册等 https://github.com/Notec17/SLProject - 10.3 ComputerGraphics
包含众多计算机图形学相关学习网站,以及学习资料,按不同学习程度进行划分 https://github.com/Notec17/ComputerGraphics - 10.4 Computer_Graphics
华中科技大学《计算机图形学》MOOC实验作业参考答案以及解题思路等 https://github.com/Notec17/Computer_Graphics - 10.5 ComputerGraphics-OpenGL
有关使用OpenGl学习计算及图形学 https://github.com/Notec17/ComputerGraphics-OpenGL
由于图形学相关的内容大部分尚未学习到,所以此次fork的仓库可能有部分内容是重复的,但是不影响学习