2020寒假作业2

这个作业属于哪个课程 2020春W班 (福州大学)
这个作业要求在哪里 寒假作业(2/2)
这个作业的目标 开发一个疫情统计程序
作业正文 作业正文
其他参考文献 杨助教提供的github简单教程

1. Github地址

github仓库

2. PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 30 25
Estimate 估计这个任务需要多少时间 1760 1855
Development 开发 450 400
Analysis 需求分析 (包括学习新技术) 350 400
Design Spec 生成设计文档 50 40
Design Review 设计复审 20 20
Coding Standard 代码规范 (为目前的开发制定合适的规范) 20 15
Design 具体设计 150 170
Coding 具体编码 500 540
Code Review 代码复审 20 40
Test 测试(自我测试,修改代码,提交修改) 60 75
Reporting 报告 40 70
Test Report 测试报告 30 30
Size Measurement 计算工作量 10 10
Postmortem & Process Improvement Plan 事后总结, 并提出过程改进计划 30 20
合计 1760 1855

3. 思路描述

看到题目之后,因为我们传入的命令参数会被存在main函数的args[]数组里,所以第一想法是对args[]数组里的命令参数进行识别,对于-type和-province这种有多个参数的另外设计方法去获取其参数。然后就是对要读取的日志的各种信息的提取,我使用java正则去获取,对于这些信息的保存我创建了province类去保存。

4. 流程图

main函数分析命令参数
读取日志
输出文件

5. 代码说明

  • 开发语言:Java
  • JDK版本:1.8
  • 开发环境:IDEA
定义province类
 class Province implements Comparable<Province>`
 {
    private String province;
    private int ip = 0,sp = 0,cure = 0,dead = 0;
    public Province(String province)
    {
        this.province = province;
    }
在类里自定义省份排序,全国需在第一
 public int compareTo(Province a)
    {
        String province1 = this.province;
        String province2 = a.province;
        Collator instance = Collator.getInstance(Locale.CHINA);
        if(province1.indexOf("重") >= 0){
            province1 = province1.replaceAll("重", "冲");//多音字重chong庆
        }
        if(province2.indexOf("重") >= 0){
            province2 = province2.replaceAll("重", "冲");
        }
        if(province1.equals("全国")) return -1; // 全国排第一
        else if(province2.equals("全国")) return 1;
        return instance.compare(province1,province2);  //按拼音排序
    }
main函数获取args[]里的命令参数
 for(int j = 0;j < args.length;j++) {
            if(args[j].equals("list")) listjudge1++;
            else if(args[j].equals("-log"))
            {
                log = args[j + 1 ];
                listjudge1++;
            }
            else if(args[j].equals("-out"))
            {
                out = args[j + 1];
                listjudge1++;
            }
            else if(args[j].equals("-date")) date = args[j + 1];
            else if(args[j].equals("-type"))
            {
                listjudge3 = 1;
                addtype(args,j,outinformation);
            }
            else if(args[j].equals("-provence"))
            {
                listjudge2 = 1;
                addprovence(args,j,proinformation,proList);
            }
        }
        if(listjudge1!=3||(listjudge2==0&&!proinformation.isEmpty())||(listjudge2==1&&proinformation.isEmpty())
        ||(listjudge3==0&&!outinformation.isEmpty())||(listjudge3==1&&outinformation.isEmpty()))
        {
            System.out.println("命令错误");
            System.exit(0);
        }
获取log提供路径下的日志名
  public static void getAllFileName(String path,ArrayList<String> listFileName) //得到日志名字
    {
        String patterndate = "\\d+-\\d+-\\d+";
        Pattern date = Pattern.compile(patterndate); // 创建 Pattern 对象
        File file = new File(path);
        String [] names = file.list();
        if(names != null){
            String [] completNames = new String[names.length];
            for(int i=0;i < names.length;i++){
                Matcher Date = date.matcher(names[i]); // 创建 matcher 对象
                if(Date.find()) completNames[i] = Date.group(0);
            }
            listFileName.addAll(Arrays.asList(completNames));
        }
    }
将得来的日志名与date参数比对
  for(String name:listFileName)
        {
            if(date==null)
            {
                InformationProcessing(log+name+".log.txt",proList,allpro);
                continue;
            }
            else if(listFileName.get(listFileName.size()-1).compareTo(date)<=0) //若输入的日期超出最新的日志范围
            {
                System.out.println("输入的日期有错");
                System.exit(0);
            }
            else if (listFileName.get(0).compareTo(date) > 0) break; //若输入日期小于最旧的日志
            else if(name.compareTo(date) > 0) break;
            InformationProcessing(log+name+".log.txt",proList,allpro);
        }
用java正则提取日志里的信息
  public static void InformationProcessing(String Path,List<Province> proList,Province allpro) //日志信息处理
    {
        int people;
        String pattern = ".*//.*";
        String pattern0 = "(\\d+)";
        String pattern0_1 = ".*感染患者.*";
        String pattern0_2 = ".*疑似患者.*";
        String pattern1 = ".*新增.*";
        String pattern2 = ".*流入.*";
        String pattern3 = ".*死亡.*";
        String pattern4 = ".*治愈.*";
        String pattern5 = ".*确诊感染.*";
        String pattern6 = ".*排除.*";
        Pattern number = Pattern.compile(pattern0); // 创建 Pattern 对象
        try
        {
            File file = new File(Path);
            if(!file .exists())
            {
                System.out.println("路径错误");
                System.exit(0);
            }
            BufferedReader br = new BufferedReader(new FileReader(file));
            String str = null;
            while ((str = br.readLine()) != null)
            {
                Matcher num = number.matcher(str); // 现在创建 matcher 对象
                String arrays[] = str.split(" ");
                if(Pattern.matches(pattern,str)) continue; // 跳过注释内容
                addlist(arrays[0],proList);
                for (Province province1 : proList) {
                    if (arrays[0].equals(province1.getprovince())&&num.find())
                    {
                        people = Integer.valueOf(num.group(0));
                        if(Pattern.matches(pattern1,str)) // 新增
                        {
                            if(Pattern.matches(pattern0_1,str)) // 新增感染患者
                            {
                                province1.setip(province1.getip() + people);
                                allpro.setip(allpro.getip() + people);
                            }
                            else if(Pattern.matches(pattern0_2,str)) //新增疑似患者
                            {
                                province1.setsp(province1.getsp() + people);
                                allpro.setsp(allpro.getsp() + people);
                            }
                        }
                        else if(Pattern.matches(pattern2,str)) //从省一流入省二
                        {
                            addlist(arrays[3],proList); //判断省二有没有在列表里边
                            for (Province province2 : proList) {
                                if (arrays[3].equals(province2.getprovince()))
                                {
                                    if(Pattern.matches(pattern0_1,str))
                                    {
                                        province1.setip(province1.getip() - people);
                                        province2.setip(province2.getip() + people);
                                    }
                                    else if(Pattern.matches(pattern0_2,str))
                                    {
                                        province1.setsp(province1.getsp() - people);
                                        province2.setsp(province2.getsp() + people);
                                    }
                                }
                            }
                        }
                        else if(Pattern.matches(pattern3,str)) //死亡 dead+n,ip-n
                        {
                            province1.setdead(province1.getdead() + people);
                            province1.setip(province1.getip() - people);
                            allpro.setdead(allpro.getdead() + people);
                            allpro.setip(allpro.getip() - people);
                        }
                        else if(Pattern.matches(pattern4,str)) //治愈 cure+n,ip-n
                        {
                            province1.setcure(province1.getcure() + people);
                            province1.setip(province1.getip() - people);
                            allpro.setcure(allpro.getcure() + people);
                            allpro.setip(allpro.getip() - people);
                        }
                        else if(Pattern.matches(pattern5,str)) //确诊感染 sp-n,ip+n
                        {
                            province1.setip(province1.getip() + people);
                            province1.setsp(province1.getsp() - people);
                            allpro.setip(allpro.getip() + people);
                            allpro.setsp(allpro.getsp() - people);
                        }
                        else if(Pattern.matches(pattern6,str)) //排除 sp-n
                        {
                            province1.setsp(province1.getsp() - people);
                            allpro.setsp(allpro.getsp() - people);
                        }
                    }
                }
            }
        } catch (IOException  e) {
            e.printStackTrace();
        }
    }
有两个对象数组若有指定provence则输出proinformation对象数组
        for(Province province : proList)
        {
            for(Province pro : proinformation)
            {
                if(province.getprovince().equals(pro.getprovince()))
                {
                    pro.setip(province.getip());
                    pro.setsp(province.getsp());
                    pro.setcure(province.getcure());
                    pro.setdead(province.getdead());
                }
            }
        }
        Collections.sort(proList);
        Collections.sort(proinformation);
        if(listjudge2==1) InformationOut(out,proinformation,outinformation);
        else InformationOut(out,proList,outinformation);
以out提供的路径以type参数输出文件
    public static void InformationOut(String out,List<Province> proList,List<String> outinformation) //写出日志信息
    {
        out = out.trim();
        String Path = out.substring(0,out.lastIndexOf("\\")); //分离得到路径
        try {
            File file = new File(Path);
            if (!file.exists())
            {
                System.out.println("路径错误");
                System.exit(0);
            }
            BufferedWriter wr = new BufferedWriter(new FileWriter(out));
            for (Province province : proList)
            {
                if (outinformation.isEmpty())
                {
                    wr.write(province.getprovince() + "共有感染患者" + province.getip() + "人 疑似患者" +province.getsp()
                            + "人 治愈" + province.getcure() + "人 死亡" + province.getdead() + "人\n");
                }
                else
                {
                    wr.write(province.getprovince() + "共有");
                    for (String outthing : outinformation)
                    {
                        if(outthing.equals("ip"))  wr.write("感染患者" + province.getip() + "人 ");
                        if(outthing.equals("sp")) wr.write("疑似患者" + province.getsp() + "人 ");
                        if(outthing.equals("cure")) wr.write("治愈" + province.getcure() + "人 ");
                        if(outthing.equals("dead")) wr.write("死亡" + province.getdead() + "人 ");
                    }
                    wr.write("\n");
                }
            }
            wr.write("// 该文档并非真实数据,仅供测试使用");
            wr.flush();
            wr.close();
        }catch (IOException  e) {
            e.printStackTrace();
        }
    }

6. 单元测试

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

7. 代码覆盖率


8. 性能分析

9. 我的命名规范

我的命名规范

10. 我的心路历程

一开始也是有的虚的,毕竟我自我感觉我的基础其实不是那么牢靠,而这次作业又是老长一条作业文档,需求也多,怕自己无法完成。
同时像GitHub,单元测试之类也是之前自己未有接触的事物。因而这次作业给我的压力也是挺大的。
所以我不再是赖到快交作业才开始做的学生了,这次我早早的开始作业2的旅途,自学各种作业需求的东西到,慢慢的就大概摸索出个所以然来了。
因为我的舍友都是另一个老师的班的,他们作业比我要晚交。结果就是这次我居然成了先行军,为他们说github之类的时候,我的理解也就慢慢深刻起来。
直到最后我完成了这份作业。感觉有种克服艰难险阻的快感!

11. 5个仓库

前端常用组件 https://github.com/zhiqiang21/WebComponent
前端开发者手册 学习前端的实践手册
Web前端开发技术栈 https://github.com/unruledboy
大前端工具集——程序猿的百宝箱 https://github.com/nieweidong
前端开发笔记本 https://github.com/li-xinyang
posted @ 2020-02-18 18:03  炸毛兔  阅读(147)  评论(3编辑  收藏  举报
🙋 /* 功能:生成鼠标点击特效 */