软件工程实践第二次作业 处理世界游泳锦标赛跳水项目相关数据

#

软件工程实践第二次作业

222100309许君毓

这个作业属于哪个课程软件工程实践-W班
这个作业要求在哪里软件工程实践寒假作业
这个作业的目标完成对世界游泳锦标赛跳水项目相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序

目录

GitCode项目地址

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

PSP表格

PSP预估耗时实际耗时
学习爬虫,爬取数据2天2天
复习Java1天1天
需求分析1天1天
编写代码3天3天
测试2天2天
性能优化2天2天

解题思路描述

  1. 先将数据爬取下来,需要学习Python知识
  2. 将数据保存为CSV,后学习Java处理CSV文件的API
  3. 考虑对于women 1m springboard这样的比赛结构可以用字符串分割然后用作树状结构来处理数据
  4. 设计单例类来保存运动员和比赛的信息,其中比赛类需要知道参加的选手
  5. 设计一个工具类来对输入数据进行分流处理,提取信息输出到指定文件

接口设计和实现过程

1.爬取数据
pFY7GnK.png

Pyhthon代码:

import pandas
import requests
import pandas as pd
header={
'User-Agent':'https://api.worldaquatics.com/fina/events/108c795d-5e4f-4dc6-acea-0bc70bfd1928'
}
list=[]
response=requests.get(url,header)
result=response.json()
disciplineName=result['DisciplineName']
for competition in result['Heats']:
    competitionName=competition['Name']
    for athleteGoal in competition['Results']:
        totalPoint=athleteGoal['TotalPoints']
        athleteName=athleteGoal['FullName']
        athlete_rank=athleteGoal['Rank']
        athlete_detailGoal=''
        i=0
        for smallGoal in athleteGoal['Dives']:
            athlete_detailGoal+=smallGoa>['DivePoints']
            if(i!=len(athleteGoal['Dives'])-1):
                athlete_detailGoal+='+'
            i=i+1
        athleteDetail={
            'Name':athleteName.replace('/','&'),
            'Rank':athlete_rank,
            'DisciplineName':disciplineName,
            'Session':competitionName,
            'TotalPoints':totalPoint,
            'DetailPoints':athlete_detailGoal
        }
        list.append((athleteDetail))
pdData=pandas.DataFrame(list)
pdData.to_csv(''+disciplineName+'.csv',index=False)

导出CSV文件:
pFY7L4J.png
2.用Java存贮静态数据
决定用单例模式来存贮Athlete和Event两个类
pFtp03T.png
3.设计CSVReader工具类来进行读取数据
4.设计DivingInformSearch工具类来进行数据在input和output文件的读和写
##代码执行过程

首先,由CSVReader里的PrintAthleteInform方法和ReadCompetitionDetail将SingleInstance类中的HashMap<String,Athlete>athletes(运动员信息)和HashMap<String,Event>events(赛事信息)填充完整。接着,将命令行接收到的input和output文件地址传递给DivingInformSearch类的DistributeDivingPath,该静态方法逐行解析input文件中的信息,(若该行信息输入错误则抛出ErrorException(自定义异常类),若改行信息结构错误导致无法解析比赛项目则抛出NotFoundEventException(自定义异常类),接着由程序处理不同异常类的输出结果),若解析为‘players’,则调用WriteAthleteInform静态方法,
若解析为‘result …’则调用WriteCompetitionInform方法,将信息写入output文件
###排序

  1. 对Players进行按国际首字母升序排序
    设计AthleteBaseInformComparator类继承自Comparator
    pFUsp8S.png
    在WriteAthleteInform调用前先将HashMap<String,Athlete>athletes里的每一个players取出构建一个ArrayList,调用ArrayList的Sort方法传入AthleteBaseInformComparator类
    pFUs9gg.png
  2. 对每场比赛的排序
    • 对只关心结果的排序(没有detail),使用自定义的EventFinalComparator(继承自Comparator),只比较Final赛的最终成绩pFUsJ56.png因为Event类中存放ArrayList,所以可以通过Event方法间接调用Sort方法进行排序pFUsyIP.png
    • 对关心不同Session的结果排序,使用自定义的EventComparator(继承自Comparator),该类会从Preliminary,Semifinal,Final逐个比较pFUs4qs.pngpFUsIZn.png调用时也是间接使用Event类中的SortAthleteDetail方法进行排序
    • 双人赛,名字排序在爬取数据时已经排好

关键代码展示

  1. 非详细输出
if(!detail)
        {
            SingleInstance.GetInstance().events.get(eventName).sortAthlete();
            ArrayList<Athlete>athletes=SingleInstance.GetInstance().events.get(eventName).getAthletes();
            for(int i=0;i<athletes.size();i++)
            {
                Athlete a=athletes.get(i);
                SessionResult finalResult=a.competitionDetail.get(eventName).get(sessionName[0]);
                StringBuilder sb=new StringBuilder("");
                sb.append("Full Name:").append(a.fullName).append("\r\n");
                sb.append("Rank:").append(finalResult.rank).append("\r\n");
                sb.append("Score:").append(finalResult.smallPoints).append("=").append(finalResult.totalPoints).append("\r\n");
                sb.append("-----\r\n");
                fw.write(sb.toString());

            }fw.flush();
        }
  1. 处理csv文件的每一行
public static void dataStore(List<String>lines)
    {
        for(int i=1;i<lines.size();i++)
        {
            String[]values=lines.get(i).split(",");
           // System.out.println(values[0]+" "+values[1]+" "+values[2]+" "+values[3]+" "+values[4]+" "+values[5]+" ");
            if(SingleInstance.GetInstance().isAthleteExsits(values[0]))
            {
                Athlete a=SingleInstance.GetInstance().getAthlete(values[0]);
                a.addCompetition(values[2],values[3],new SessionResult(values[3],values[1],values[4],values[5]));
                if(!SingleInstance.GetInstance().events.get(values[2]).athletes.contains(a))
                   SingleInstance.GetInstance().events.get(values[2]).addAthlete(a);
            }
            else{
                Athlete a=new Athlete(values[0],"","");
                a.addCompetition(values[2],values[3],new SessionResult(values[3],values[1],values[4],values[5]));
                SingleInstance.GetInstance().addAthlete(values[0],a);
                if(!SingleInstance.GetInstance().events.get(values[2]).athletes.contains(a))
                   SingleInstance.GetInstance().events.get(values[2]).addAthlete(a);
            }
        }
    }

异常处理

DistributeDivingPath,该静态方法逐行解析input文件中的信息,(若该行信息输入错误则抛出ErrorException(自定义异常类),若改行信息结构错误导致无法解析比赛项目则抛出NotFoundEventException(自定义异常类),接着由程序处理不同异常类的输出结果

性能改进

1.对每名运动员的具体比赛场次信息用HashMap将Final,Semifinal,Preliminary作为键,映射SessionResult
z8z0j.png

测试

  • 白盒测试

测试控制台代码:java -jar DWASearch.jar D://input.txt D://output.txt

  1. pFaVy7V.pngpFaVckT.png

  2. D://input.txt:result women 1m springboard
    result women 3m springboard detail
    pFatpb8.png

  3. D://input.txt:result women 1m synchronised
    result women 3m synchronised detailspFaZi4S.png

  4. D://input.txt:result women 3m synchronised
    result women 3m synchronised detailpFatPUg.png

  5. D://input.txt:result men 1m springboard
    result men 3m springboard detailpFati5Q.png

  6. D://input.txt:result men1m springboard
    result men 3m springboard details
    pFaZeun.png

  7. D://input.txt:player
    Player
    Result men 3m springboard
    pFaZw4O.png

  8. D://input.txt:result men 3m synchronised
    result men 3m synchronised detail
    z8I2p.png

  9. D://input.txt:result women 3msynchronised
    result men 3m synchronised detail
    z8P3V.png

  10. D://input.txt:result women 3msynchronised
    result men 3m synchronised details
    Player
    z8ei0.png

心得体会

通过这次作业我学习了一点点Python,爬取数据让我觉得十分有趣,同时我也复习了Java,让我更加熟练地写单例类设计模式。但在性能方面的优化还存在不足,字符串的比较是否可以用树的结构进行快速分类还没有落实

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值