软件工程实践第二次作业---文件读取

这个作业属于哪个课程软件工程23春季学期社区
这个作业要求在哪里<软件工程实践第二次作业—文件读取>
这个作业的目标收集<澳大利亚网球公开赛>的相关数据、实现一个能够对赛事数据进行统计的控制台程序
其他参考文献《构建之法》、CSDN博客

Gitcode项目地址

<项目地址>

PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2030
• Estimate• 估计这个任务需要多少时间2030
Development开发400500
• Analysis• 需求分析 (包括学习新技术)200300
• Design Spec• 生成设计文档8060
• Design Review• 设计复审3030
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)2020
• Design• 具体设计3050
• Coding• 具体编码480500
• Code Review• 代码复审6050
• Test• 测试(自我测试,修改代码,提交修改)10090
Reporting报告100120
• Test Repor• 测试报告1010
• Size Measurement• 计算工作量3040
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划2020
合计16001850

解题思路描述

数据处理

  • 获取数据
    题目要求从<澳大利亚网球公开赛>上获取数据,步骤是从浏览器右键选择底部的检查,再进去找到网络,输入players和result刷新后得到请求的url,截取得到的字符串保存得到相应的json数据。

    • 这边示例Q1数据的获取
      从网站上获取原始数据
      *Q1数据

Q1数据- 分析数据
获取json数据之后对这部分数据进行分析,我使用的是阿里巴巴的fastjson,从网站上下载相应的jar包,并且建立依赖。

fastjson包

功能实现思路

  • json解析
    在这里插入图片描述

  • players的输出
    players指令的输出是作业的第一题,也是最简单的起手。首先我们需要观察players.json数据文件,观察通过键值直接获取player对象数组,再从这个数组中循环得到player对象,再根据键值输出相应需要输出的数据,并且关注输出格式。
    在这里插入图片描述

  • result的输出
    result的输出则包含了日期的比赛结果和Q1 Q2 Q3 Q4的比赛结果,但是都是大同小异的。这次的题目则难度大于上一个单单输出players,我们需要先从当日比赛的队伍中找到对应的胜利的队伍,并且根据胜利队伍的id从players.json里找到相应的队伍,再从队伍里的选手id匹配相应的选手,再输出相应的信息。

接口设计和实现过程

AOSearch 完成命令的读入,以及完成错误的输出
public static String readJsonFile(String fileName) 完成json数据的获取
public static String OutResult(String function) 传入命令,获取对应json文件,解析json数据,输出比赛结果
public static String OutPlayers() 解析json数据,输出选手信息
public static void writeTxt(String txtPath,String content) 输出数据到output.txt
public static List readStringFromtxt(String txtpath) 从input.Txt获取命令
在这里插入图片描述

关键代码展示

public static void OutPlayers(){    //输出选手信息
        //String path = StyleUtil.class.getClassLoader().getResource("test.json").getPath();
        String path = "222000125/src/Data/players.json";
        String str = readJsonFile(path);
        JSONObject jsonObj = JSON.parseObject(str);
        JSONArray players = jsonObj.getJSONArray("players");
        String infop="";

        for (Object player : players) {
            JSONObject play =(JSONObject)player;
//            System.out.print("full_name:");
//            System.out.println(play.getString("full_name"));
            infop += "full_name:";
            infop += play.getString("full_name");
            infop += "\n";
//            JSONObject play =(JSONObject)player;
//            System.out.print("gender:");
//            System.out.println(play.getString("gender"));
            infop += "gender:";
            infop += play.getString("gender").equals("M")?"male":"female";
            infop += "\n";
            JSONObject nationality = play.getJSONObject("nationality");
//            System.out.print("nationality:");
//            System.out.println(nationality.getString("name"));
            infop += "nationality:";
            infop += play.getString(nationality.getString("name"));
            infop += "\n";
            infop += "-----\n";
        }
        writeTxt("222000125/src/output.txt",infop);

    }
public static void writeTxt(String txtPath,String content){  //输出相应的信息到output.Txt
    FileOutputStream fileOutputStream = null;
    File file = new File(txtPath);
    try {
        if(file.exists()){
            //判断文件是否存在,如果不存在就新建一个txt
            file.createNewFile();
        }
        fileOutputStream = new FileOutputStream(file,true);
        fileOutputStream.write(content.getBytes());
        fileOutputStream.flush();
        fileOutputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public static void OutResult(String function){    //输出比赛信息
        String path = "222000125/src/Data/";
        String[] strs = function.split(" ");
        strs[1] += ".json";
        path += strs[1];//生成对应的日期的json文件地址  ,通过拼接形成对应的json文件地址
        String str = readJsonFile(path);
        JSONObject jsonObj = JSON.parseObject(str);
        JSONArray matches = jsonObj.getJSONArray("matches");  //获得matches数组
        String t1,t2,t3,t4,t5,t6;        //用于存放比赛分值
        String []arr = new String[2];
        String infor="";
        for (Object match : matches){
            JSONObject matc = (JSONObject)match;
            JSONObject match_status = matc.getJSONObject("match_status"); //得到对象
            JSONArray team = matc.getJSONArray("teams");  //得到team数组
//            JSONObject score =team.getJSONArray();
            if(match_status.getString("abbr").equals("W/O")){  //弃赛判断
                System.out.println("W/O");
                infor += "W/O";
                System.out.println("-----");
                infor += "\n";
            }
            else{               //输出比赛时间
                System.out.print("time:");
                System.out.println(matc.getString("actual_start_time"));
                infor += "time:";
                infor += matc.getString("actual_start_time");
                infor += "\n";
                ------------
if(tm1.containsKey("status")){  //说明第一个队伍对象是胜者
                        teamId = tm1.getString("team_id");
                        for(Object teamss :teams){
                            JSONObject teamsss = (JSONObject)teamss;
                            if(teamsss.getString("uuid").equals(teamId)){  //将获胜队伍与play表里的队伍uuid匹配
 for (Object player : players) {
                                JSONObject play = (JSONObject) player;
          //寻找相应的选手  并且强制先寻找第一个if语句也就是数组的第一个元素
                                if (playuidA.getString(0).equals(play.getString("uuid"))) {
                                System.out.print(play.getString("short_name"));  //注意需要输出缩写
                                infor += play.getString("short_name");
                                n = 1;
                                }
                               else if(n==1 && playuidA.size()==2 && playuidA.getString(1).equals(play.getString("uuid"))){
                                        System.out.print(" & ");
                                        infor += " & ";
                                        System.out.print((play.getString("short_name")));
                                        infor += play.getString("short_name");
                                        n = 100;
                                    }
                                }
                            }
独到之处:这段代码运行时发现,选手输出顺序有时会混乱,双打前后部分。
所以在寻找选手时我使用了类似互斥锁思想的设计,让程序必须先查找获取的第一个选手,
再查找第二个选手。
下边是代码
int n = 100; //定义用于后边选手搜索顺寻的先后
for (Object player : players) {
         JSONObject play = (JSONObject) player;
//寻找相应的选手  并且强制先寻找第一个if语句也就是数组的第一个元素
         if (playuidA.getString(0).equals(play.getString("uuid"))) {
           System.out.print(play.getString("short_name"));  //注意需要输出缩写
           infor += play.getString("short_name");
           n = 1;
	   }
         else if(n==1 && playuidA.size()==2 && playuidA.getString(1).equals(play.getString("uuid"))){
           System.out.print(" & ");
           infor += " & ";
           System.out.print((play.getString("short_name")));
           infor += play.getString("short_name");
           n = 100;
         }
}

性能改进

使用caffeine.jar,使用cache,对找到的数据进行缓存,下次若再需使用这个数据,则直接取用不用再解析json数据。这样代码运行的速度提高了很多。
运行一条
在这里插入图片描述
运行一千条
在这里插入图片描述

单元测试

提高覆盖率要尽可能覆盖到程序中不同的分支结构,Lib类中有一些处理流异常的指令无法覆盖到,所以Lib类的覆盖率会相对低一点
在这里插入图片描述

异常处理

  • AOSearch.java(命令行参数异常处理)
            if(parts.length==1) {
                if (!parts[0].equals("players")&&!parts[0].equals("result")) {
                    info += "Error\n" + "-----\n";
                    Fun.writeTxt("output.txt", info);
//                    Fun.OutPlayers();
                } else if(parts[0].equals("result")){
                    info+="N/A\n"+"-----\n";
                    Fun.writeTxt("output.txt",info);
                } else  {
                    if (cache.getIfPresent(comd) == null) { //如果缓存中没有这条指令则将其存入缓存
                        info = Fun.OutPlayers();
                        cache.put(comd, info);
                    } else  info=cache.getIfPresent(comd);//如果缓存中存在这条指令则从缓存中获取
//                    info = Fun.OutPlayers();
                     Fun.writeTxt("output.txt",info);
                }
            }
//            parts[0].equals("result")
            else if (parts.length>=2) {
                if(!parts[0].equals("result")){
                    info += "Error\n" + "-----\n";
                    Fun.writeTxt("output.txt", info);
                }
                else if (parts.length>2){
                    info+="N/A\n"+"-----\n";
                    Fun.writeTxt("output.txt",info);
                }
                else if (!Fun.judgeRight(parts[1])) {
                    info+="N/A\n"+"-----\n";
                    Fun.writeTxt("output.txt",info);
                }
                else if (Fun.judgeRight(parts[1])) {
                    if(cache.getIfPresent(comd) == null) {
                        info = Fun.OutResult(comd);
                        cache.put(comd, info);
                    }else info=cache.getIfPresent(comd);
//                    info = Fun.OutResult(comd);
                    Fun.writeTxt("output.txt",info);
  • Fun.java(文件打开异常)
        try {
            File jsonFile = new File(fileName);
            FileReader fileReader = new FileReader(jsonFile);

            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

心得体会

在刚开始拿到这个题目的时候,我确实是没有什么思路的,但是在一些已经开始写代码的同学的解释下,我清楚了这次作业的整个流程以及拥有了一个大概的思路。
这次作业的难度所在在于第一次真正的去这样像模像样的去完成一个功能,其中有着之前没有接触过的东西,在从零到一的路上,我学会了使用Java去解析复杂的json数据,自己从网络上爬取相应的json数据,学会了使用fastjson去解析数据,理清复杂的json数据内的取数据的流程。以及封装自己的代码,尝试着去优化自己的代码,进行单元测试,测试覆盖率。
总之在这次作业,我明白了自己拥有的技术栈的缺陷,以及理解需求能力和,自学能力的不足。在以后的学习中,我应该更注重编码的规范,技术栈的扩展,只有会的多自学能力才能慢慢提高。以后遇到这样的问题才能更加的得心应手。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VengaZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值