软件工程实践第二次作业——个人实战

222100310许家榕 2024-02-26 11:57:22

软件工程实践第二次作业——个人实战

这个作业属于哪个课程软件工程实践-2023学年-W班
这个作业要求在哪里软件工程实践第二次作业——个人实战
这个作业的目标完成对世界游泳锦标赛跳水项目相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序
其他参考文献《构建之法》《源代码管理》

目录

  • 软件工程实践第二次作业——个人实战
  • Gitcode项目地址
  • PSP表格
  • 解题思路描述
  • 对于数据的获取
  • 开始时想到了三个方法:
  • Json的解析
  • 对input.txt文件的读取
  • 接口设计和实现过程
  • 接口设计
  • 接口实现
  • 关键代码展示
  • 性能改进
  • 单元测试
  • 异常处理
  • 心得体会

Gitcode项目地址

https://gitcode.net/xjr16/project-java

PSP表格

软工开发阶段预估耗时(分钟)实际耗时(分钟)
计划1020
开发420600
需求分析 (包括学习新技术)3060
生成设计文档1530
设计复审1515
代码规范 (为目前的开发制定合适的规范)55
具体设计4040
具体编码300520
代码复审60180
测试(自我测试,修改代码,提交修改)6030
报告3030
测试报告3030
计算工作量1010
事后总结, 并提出过程改进计划6030
合计11101800

解题思路描述

对于数据的获取

开始时想到了三个方法:

  • 通过爬虫软件获取网页资源获取信息
  • 通过获取网站api获取json信息进行解析
  • 通过获取网站api获取json信息进行解析后,将其转为csv文件进行储存,通过代码调取csv文件进行信息获取
  • 最后选择了第三点
  • 获取api

img

  • 解析api并转换成csv

    img

Json的解析

  • 学习maven管理资源包的办法
  • 导入json包进行解析
  • 在getdata中成功获取到信息

    对input.txt文件的读取

  • scanner.nextLine().trim()的读取获取input.txt里面的内容再调用函数对output.txt进行输出

接口设计和实现过程

接口设计

  • 通过在抽象类中定义构造函数,并在子类中使用super关键字调用父类的构造函数,可以实现在新类中直接获取不同功能所需的信息
  • 子类再通过获取的信息,完成具体的函数实现其功能

    接口实现

img

  • 通过运行getData获取csv数据表格
  • CompletionResultCompletionResultDetailPlayer都继承与AbstractPlayers,分别处理不同指令

关键代码展示

  • 基础功能

      public Player(String fullName, String gender, String country) {
          this.fullName = fullName;
          this.gender = gender;
          this.country = country;
      }
    
      @Override
      public String toString() {
          return "Full Name:" + fullName + "\nGender:" + gender + "\nCountry:" + countryName(country) + "\n-----\n";
      }
      public static void printPlayers(List<Player> players, PrintWriter writer) {
          for (Player player : players) {
              writer.print(player);
          }
      }
    
      public static List<CompletionResult> readCompletionResult(String Result) throws FileNotFoundException {
          List<CompletionResult> CompletionResult = new ArrayList<>();
          InputStream stream = CompletionResult.class.getResourceAsStream(Result);
          if (stream == null) {
              throw new FileNotFoundException( Result + " not found");
          }
          try (Scanner scanner = new Scanner(stream)) {
              scanner.nextLine(); // skip header line
              while (scanner.hasNextLine()) {
                  String[] data = scanner.nextLine().split(",");
                  String[] divePoints = data[2].split(" \\+ ");
                  CompletionResult.add(new CompletionResult(data[0].trim(), data[5].trim(), divePoints, data[3].trim(), data[4].trim(), data[6].trim(), data[1].trim()));
              }
          }
          return CompletionResult;
      }
    
      public static void printCompletionResult(List<CompletionResult> CompletionResult, PrintWriter writer) {
          for (CompletionResult player : CompletionResult) {
              writer.println("Full Name:" + player.getName());
              writer.println("Rank:" + player.getRank());
    
              //去除null值
              String scores = Arrays.stream(player.getDivePoints())
                      .filter(Objects::nonNull)
                      .collect(Collectors.joining(" + "));
    
              writer.println("Score:" + scores + " = " + player.getTotalPoints());
              writer.println("-----");
          }
      }
    
  • 主类

    public class DWASearch {
      public static void main(String[] args) throws IOException {
          List<Player> players = new ArrayList<>();
          InputStream stream = DWASearch.class.getResourceAsStream("/players.csv");
          if (stream == null) {
              throw new FileNotFoundException("/csv/players.csv not found");
          }
          try (Scanner scanner = new Scanner(stream)) {
              scanner.nextLine(); // skip header line
              while (scanner.hasNextLine()) {
                  String[] data = scanner.nextLine().split(",");
                  players.add(new Player(data[3].trim(), data[1].trim(), data[0].trim()));
              }
          }
    
          try (Scanner scanner = new Scanner(new File("input.txt"));
               PrintWriter writer = new PrintWriter(("output.txt"))) {
              while (scanner.hasNextLine()) {
                  String command = scanner.nextLine().trim();
                  if (command.isEmpty()) {
                      continue; // skip empty lines
                  }
                  if ("players".equals(command)) {
                      printPlayers(players, writer);
                  } else if (command.startsWith("result ")) {
                      String condition = command.substring(7); // 获取后面的值
                      boolean hasDetail = condition.endsWith(" detail");
                      condition = hasDetail ? condition.substring(0, condition.length() - 7) : condition; // 判断条件后的detail
                      switch (condition) {
                          case "women 1m springboard":
                              if (hasDetail) {
                                  printDetailedCompletionResult(readCompletionResult("/Women 1m Springboard.csv"), writer);// 这里是当指令包含detail时执行的代码
                              }
                              else
                                  CompletionResult.printCompletionResult(CompletionResult.readCompletionResult("/Women 1m Springboard.csv"), writer);
                              break;
                              //...
                          default:
                              writer.println("N/A");
                              writer.println("-----");
                              break;
    
                      }
                  }
                  else {
                      writer.println("Error");
                      writer.println("-----");
                  }
              }
          }
      }
    
  • datil功能实现

    public static Map<String, CompletionResultDetail> readCompletionResult(String Result) throws FileNotFoundException {
          Map<String, CompletionResultDetail> playerScoresMap = new HashMap<>();
          try (Scanner scanner = new Scanner(Objects.requireNonNull(CompletionResultDetail.class.getResourceAsStream(Result)))) {
              scanner.nextLine(); // skip header line
              while (scanner.hasNextLine()) {
                  String[] data = scanner.nextLine().split(",");
                  String[] divePoints = data[2].split(" \\+ ");
                  String fullName = data[0].trim();
                  String phaseName = data[6].trim();
                  String scores = Arrays.stream(divePoints)
                          .filter(Objects::nonNull)
                          .collect(Collectors.joining(" + "));
                  CompletionResultDetail completionResultDetail = playerScoresMap.computeIfAbsent(fullName, k -> new CompletionResultDetail(fullName, data[1].trim(), data[5].trim()));
                  completionResultDetail.addScore(phaseName, scores);
                  completionResultDetail.addRank(phaseName, data[4].trim()); // 添加排名
                  completionResultDetail.setTotalPoints(data[3].trim()); // 读取总分
              }
          }
          return playerScoresMap;
      }
    
      public static void printDetailedCompletionResult(Map<String, CompletionResultDetail> playerScoresMap, PrintWriter writer) {
          for (Map.Entry<String, CompletionResultDetail> entry : playerScoresMap.entrySet()) {
              writer.println("Full Name:" + entry.getKey());
              writer.println("Rank:" + entry.getValue().getRank("Preliminaries") + " | " + entry.getValue().getRank("Semifinals") + " | " + entry.getValue().getRank("Finals")); // 打印排名
              writer.println("Preliminary Score:" + entry.getValue().getScore("Preliminaries") + " = " + entry.getValue().getTotalPoints());
              writer.println("Semifinal Score:" + entry.getValue().getScore("Semifinals") + " = " + entry.getValue().getTotalPoints());
              writer.println("Final Score:" + entry.getValue().getScore("Finals") + " = " + entry.getValue().getTotalPoints());
              writer.println("-----");
          }
      }
    

    性能改进

  • 文件读取优化:在所有涉及文件读取的地方,可以使用BufferedReader来替换Scanner,以提高文件读取的效率

  • 替换前

    img

img

  • 替换成BufferedReader后

    img


    img

单元测试

  • 测试代码

img

  • 测试结果

    img

异常处理

  • 对文件的读取做出了异常处理

    img

心得体会

  • 学习到了基础的开发流程,对文件与流,json解析与api获取都有了新的认识,从中获益许多。
...全文
346 1 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
助教邓雨红 2024-03-13
  • 打赏
  • 举报
回复

异常处理这块没有描述哦,异常处理也是编写代码时很重要的环节,最好说明一下哈。

310

社区成员

发帖
与我相关
我的任务
社区描述
福州大学的软件工程实践-2023学年-W班
软件工程需求分析结对编程 高校 福建省·福州市
社区管理员
  • FZU_SE_teacherW
  • Pity·Monster
  • 助教张富源
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧