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

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获取都有了新的认识,从中获益许多。
...全文
613 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
助教邓雨红 2024-03-13
  • 打赏
  • 举报
回复

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

内容概要:本文针对多渗透率电动汽车接入对配电网造成的影响,系统性地研究了其承载能力的评估方法,提出了一套融合多类型分布式能源的综合性评估体系。研究首先建立了包含配电网、电动汽车、分布式光伏及静止无功补偿装置(SVC)的协同运行基础模型,并据此构建了涵盖一次设备安全、负荷平稳性、电能质量与系统效率四个维度的多维评价指标体系。为实现客观、全面的量化评估,采用基于熵权法的客观赋权与模糊综合评价相结合的双层评分模型,有效避免了主观赋权的偏差,增强了评估结果的科学性与可信度。通过典型算例仿真,系统分析了不同电动汽车渗透率水平下各指标的演变规律,并开展了指标灵敏度分析,验证了所提评估模型的有效性、合理性和鲁棒性。; 适合人群:具备电力系统、电气工程及其自动化等相关专业背景,熟悉Matlab编程与电力系统仿真工具,从事新能源并网、智能配电网规划、电动汽车充放电管理等领域研究的研究生、高校科研人员及电网公司、设计院的工程技术人员。; 使用场景及目标:① 用于定量评估城市或区域配电网在不同电动汽车发展规模下的接纳能力与安全裕度;② 为电网规划部门制定充电基础设施布局、配电网升级改造方案提供决策依据;③ 支持研究高比例可再生能源与电动汽车耦合对电网稳定性的影响,优化负荷管理与无功补偿策略。; 阅读建议:建议读者结合文中的Matlab代码,动手复现算例仿真过程,深入理解熵权法计算权重与模糊综合评价的实现逻辑,并尝试调整电动汽车渗透率、光伏出力等关键参数,观察评价结果的变化趋势,从而深刻掌握模型的内在机理与应用方法。
内容概要:本文系统研究了分布式光伏储能系统的优化配置方法,重点聚焦于多渗透率电动汽车接入背景下配电网承载能力的评估问题。研究构建了涵盖配电网基础架构、电动汽车充放电行为、分布式光伏出力特性及无功补偿设备运行的协同仿真模型,并建立了集成设备安全、负荷特性、电能质量和系统效率的多维评价指标体系。创新性地提出基于熵权法与模糊综合评价相结合的双层评分模型,实现对承载能力的客观赋权与科学量化评估。通过Matlab平台进行算例仿真,分析不同电动汽车渗透率下的系统运行特性,开展关键指标的灵敏度分析,验证了方法的有效性与鲁棒性,为高比例新能源与电动汽车融合发展的配电网规划、优化调度及储能配置提供了理论支撑与技术工具。; 适合人群:电力系统、新能源、智能电网、综合能源系统及相关领域的科研人员、高校研究生以及从事电网规划与运行的工程技术人员。; 使用场景及目标:①用于研究高比例分布式光伏与规模化电动汽车接入对配电网运行特性的综合影响;②为配电网承载能力的科学评估、储能系统的优化配置及电网升级改造提供决策支持;③支持相关领域课题研究、学术论文复现、毕业设计及工程项目方案论证。; 阅读建议:建议结合提供的Matlab代码进行仿真复现,深入理解熵权法计算指标权重与模糊综合评价的实现细节,通过调整电动汽车渗透率、光伏出力水平等关键参数进行多场景对比和敏感性分析,以全面掌握系统运行规律与评估模型的内在逻辑。
内容概要:本文针对传统三电平并网逆变器在谐波抑制、电网不平衡适应性及动态响应方面的不足,提出了一种基于有源中点箝位(ANPC)三电平拓扑的高性能并网控制体系。该体系融合双极性倍频脉宽调制(DPWMA)、正负序分离锁相控制与电网电压前馈控制三大核心技术,构建了“精准同步-扰动补偿-优质调制”的一体化控制架构。ANPC拓扑通过有源箝位器件实现开关损耗均衡与中点电位主动调控,显著提升系统效率与稳定性;DPWMA调制在不增加器件开关频率的前提下,使输出等效开关频率翻倍,有效降低低次谐波含量,提升波形质量;正负序分离锁相技术可精准提取电网正序分量,抑制负序扰动对锁相精度的影响,保障不平衡电网下的稳定并网;电网电压前馈控制则打破传统反馈控制的滞后局限,实现对电网扰动的快速预补偿,大幅提升系统动态响应能力与抗扰性能。通过多工况仿真验证,该复合控制策略在稳态运行、电网不平衡及动态扰动等场景下均展现出优异的电能质量、锁相精度与运行稳定性,适用于新能源发电、工业大功率变流等对并网性能要求严苛的应用场合。; 适合人群:电力电子、新能源并网、自动控制及相关领域的科研人员与工程技术人员,以及具备一定电力系统分析与控制理论基础的研究生或高年级本科生。; 使用场景及目标:①研究高电能质量、高可靠性的三电平并网逆变器设计与控制方法;②解决电网电压不平衡、畸变等非理想工况下的并网稳定性问题;③提升大功率逆变系统的动态响应速度与抗干扰能力,推动高性能逆变技术在光伏、风电、储能等新能源系统中的应用。; 阅读建议:建议结合提供的Simulink仿真模型进行实践验证,重点掌握DPWMA调制的实现逻辑、正负序分离锁相算法的设计原理以及前馈-反馈复合控制结构的搭建方法,深入理解各模块间的协同工作机制,并通过对比不同工况下的仿真结果,全面评估控制策略的有效性与鲁棒性。

315

社区成员

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

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