这个作业属于哪个课程 | 软件工程实践-2023年福大-W班 |
---|---|
这个作业要求在哪里 | 软件工程实践第二次作业——个人实战 |
这个作业的目标 | 完成对世界游泳锦标赛跳水项目相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序 |
其他参考文献 | 无 |
Gitcode项目地址
PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 50 |
• Estimate | • 估计这个任务需要多少时间 | 60 | 50 |
Development | 开发 | 1270 | 1280 |
• Analysis | • 需求分析 (包括学习新技术) | 300 | 400 |
• Design Spec | • 生成设计文档 | 30 | 20 |
• Design Review | • 设计复审 | 20 | 20 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 20 |
• Design | • 具体设计 | 40 | 30 |
• Coding | • 具体编码 | 600 | 400 |
• Code Review | • 代码复审 | 100 | 150 |
• Test | • 测试(自我测试,修改代码,提交修改) | 150 | 200 |
Reporting | 报告 | 120 | 90 |
• Test Repor | • 测试报告 | 60 | 40 |
• Size Measurement | • 计算工作量 | 40 | 30 |
• Postmortem & Process Improvement Plan | Column 2 | 20 | 20 |
合计 | 1450 | 1420 |
解题思路描述
数据获取
一开始看见爬取网页数据,想到的是爬虫技术,但是发现通过爬虫获取数据并且筛选数据极其困难,与他人交流后知道可以直接在指定网页进行数据,也就是json文件的或取,才得以简单快速地获取相关数据。
JSON文件的解析
以前并没有真正学习过json相关的内容,由于获取到的数据由若干层json数组和json对象相互层层嵌套,使用简单的json对象并不容易提取到目标数据。因此我这里根据得到的json文件的数据结构,并且使用多个JSONObject和JSONArray的数据结构相互提取,将json文件中多余数据逐层筛出,最后提取到多个指定的目标数据的JSONObject,便可以轻易地得到目标数据。
接口设计和实现过程
Athlete:运动员实体类,使用提取到的数据构造而成,并且形成目标输出格式。
ResultSimple:比赛结果实体类,使用提取到的数据构造而成,并且对数据处理后,形成目标输出格式。
DWASearch:包含了main函数入口,以及对json数据进行解析的两个关键函数getAthletes()、getResultSimple()。
关键代码展示
//功能一
public static void getAthletes(String jsonFile, BufferedWriter bw) throws IOException {
String content = FileUtils.readFileToString(new File(jsonFile), StandardCharsets.UTF_8);
JSONArray jsonArray = JSON.parseArray(content);
//层层剥取所需要的信息
for (int i = 0 ; i <jsonArray.size() ; i++) {
JSONObject jsonObject = JSON.parseObject(jsonArray.getString(i));
JSONArray jsonArray1 = JSON.parseArray(jsonObject.getString("Participations"));
for(int j = 0 ; j < jsonArray1.size() ; j++ ){
JSONObject jsonObject1 = JSON.parseObject(jsonArray1.getString(j));
Athlete athlete = new Athlete(jsonObject1.getString("PreferredFirstName"),
jsonObject1.getString("PreferredLastName")
,jsonObject1.getString("Gender"),jsonObject1.getString("NAT"));
bw.write(athlete.toString());
}
}
}
//功能二
public static void getResultSimple(String jsonFile,BufferedWriter bw) throws IOException {
String content = FileUtils.readFileToString(new File(jsonFile), StandardCharsets.UTF_8);
//剥取json文件信息
JSONObject jsonObject = JSON.parseObject(content);
JSONArray jsonArray = JSON.parseArray(jsonObject.getString("Heats"));
JSONObject jsonObject1 = JSON.parseObject(jsonArray.getString(0));
JSONArray jsonArray1 = JSON.parseArray(jsonObject1.getString("Results"));
for(int i = 0 ; i < jsonArray1.size() ; i++){
JSONObject result = JSON.parseObject(jsonArray1.getString(i));
Double total = result.getDouble("TotalPoints");
String fullName = result.getString("FullName");
int rank = result.getIntValue("Rank");
JSONArray resultDetails = JSON.parseArray(result.getString("Dives"));
Double[] score = new Double[resultDetails.size()];
for(int j = 0 ; j < resultDetails.size() ; j++){
JSONObject detail = JSON.parseObject(resultDetails.getString(j));
score[j] = detail.getDouble("DivePoints");
}
ResultSimply resultSimply = new ResultSimply(fullName,rank,score,total);
bw.write(resultSimply.toString());
}
单元测试
部分测试代码
@Test
public void mainTest() throws IOException {
String[] strings ={"input.txt","output.txt"};
DWASearch.main(strings);
}
@Test
public void getAthletesTest1() throws IOException {
String jsonFile = "src/data/athletes.json";//无异常
BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
try {
DWASearch.getAthletes(jsonFile,bw);
} catch (IOException e) {
System.out.println(jsonFile+"文件打开错误,将输出N/A");
}
}
@Test
public void getAthletesTest2() throws IOException {
String jsonFile = "src/data/athlete.json";//输出N/A
BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
try {
DWASearch.getAthletes(jsonFile,bw);
} catch (IOException e) {
System.out.println(jsonFile+"文件打开错误,将输出N/A");
}
}
@Test
public void getResultSimple1() throws IOException {
String jsonFile = "src/data/men 1m springboard.json";//无异常
BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
try {
DWASearch.getResultSimple(jsonFile,bw);
} catch (IOException e) {
System.out.println(jsonFile+"文件打开错误,将输出N/A");
}
}
@Test
public void getResultSimple2() throws IOException {
String jsonFile = "src/data/men 1m springboard.json";输出N/A
BufferedWriter bw = new BufferedWriter(new FileWriter(outputFile));
try {
DWASearch.getResultSimple(jsonFile,bw);
} catch (IOException e) {
System.out.println(jsonFile+"文件打开错误,将输出N/A");
}
}
测试数据构造思路
使用了包括非players、result开头以及detail结尾(仅测试了异常处理,暂未完成附加功能)以及文件路径不存在的指令。
测试结果
覆盖率
异常处理
if (args.length < 2) {
System.out.println("Usage: java -jar DWASearch.jar input.txt output.txt");
return;
}
try {
String[] word = line.split(" ");
//from here
if(word[0].equals("players")&&word.length==1)
{//功能一
String jsonFile = "src/data/athletes.json";
getAthletes(jsonFile,bw);
}else if(word[0].equals("result")){
if(word[word.length-1].equals("detail")){
//附加功能
//对附加功能完成异常检测(并未输出正确数据)
String jsonFile = "";
for(int i = 1 ; i < word.length-1 ; i++)
jsonFile += word[i];
String content = FileUtils.readFileToString(new File(jsonFile), StandardCharsets.UTF_8);
System.out.println("(尚未完成附加功能)");
//附加功能函数
}else{
//功能二
String[] word1 = line.split(" ",2);//提取文件名
String jsonFile = "src/data/" +word1[1]+ ".json";
getResultSimple(jsonFile,bw);
}
}
else{//指令无法识别时
bw.write("Error\n-----\n");
System.out.println("指令读取错误,将输出Error");
}
} catch (IOException e) {//文件路径找不到
bw.write("N/A\n-----\n");
System.out.println("json文件打开错误,将输出N/A");
}
当并未准确输入两个txt文件名,即输入输出文件时,程序将直接打印"Usage: java -jar DWASearch.jar input.txt output.txt"并终止返回。
对无法读取的指令输出Error和控制台打印"指令读取错误,将输出Error",文件路径不存在的指令输出N/A和控制台打印"json文件打开错误,将输出N/A"。
心得体会
在这次实战中我明白了我的专业知识还很浅薄,在第一次看见题目时由于没怎么见过和学习过json相关的知识,一开始很长一段时间在学习jsoup的知识,而对于这次作业中的使用的方法个人觉得也比较笨拙,在编程这方面我还远远不足。除此之外,我还学习到了很多新知识比如单元测试,json各类的使用,收获较大。