闲散贤咸人的博客
#博客地址:https://blog.csdn.net/socialman123/article/details/136359039
作业基本信息
项目名称 | 项目内容 |
---|---|
这个作业属于哪个课程 | 软件工程实践-2023年福大-W班 |
这个作业要求在哪里 | 软件工程实践寒假作业要求 |
这个作业的目标 | 在文章开头给出新建的Gitcode项目地址 详细阅读作业要求 完成代码编写并进行测试 撰写博客 描述解题思路 设计实现过程 关键代码展示 PSP表格 核对作业评分标准 |
其他参考文献 | … |
Gitcode项目地址
PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 1200 | 1300 |
• Analysis | • 需求分析(包括学习新技术) | 180 | 200 |
• Design Spec | • 生成设计文档 | 20 | 30 |
• Design Review | • 设计复审 | 20 | 25 |
• Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 30 | 35 |
• Design | • 具体设计 | 70 | 80 |
• Coding | • 具体编码 | 700 | 750 |
• Code Review | • 代码复审 | 60 | 60 |
• Test | • 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | 40 | 55 |
• Test Repor | • 测试报告 | 20 | 15 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 30 |
合计 | 1300 | 1415 |
解题思路描述
1.设计结构
仔细阅读题目要求,得到需要实现的三个部分:输入输出、查询三种类型的数据(palyers,reuslt …,result … detial)以及对爬取到的三种数据的解析。故需要设计文件的读取和写入结构,设计三种类型的类(Players,Game,GameDetial),对数据解析的方法单独设置一个类别。
2.爬取和解析数据
首先需要再edge上进入管理员模式后获取所需要的json结构,后保存到data包中,再使用导入Gson外部库对json文件进行解析,获得所需要的数据。
3.完成输入输出
对输入的input文件进行逐行读取,用Queue队列封装,后按顺序逐个弹出处理,对不合法的输入进行Error报错,对result后不正常文件进行N/A报错,对正确的输入进行符合规定的输出,将报错和输出结果都存入output文件中。
接口设计和实现过程
Players类,Game类,GameDetial类
作为解析后数据的封装储存,用于输出访问。
DWASearch类
包含main主函数,作为程序的入口,包含文件读取和写入的功能。
JSON类
对解析JSON文件的方法的封装,方法全采取static静态的方法。
关键代码展示
解析players数据
public static Queue<Players> getPlayers() {
try {
// 创建Gson对象
Gson gson = new Gson();
// 读取json文件
Reader reader = new FileReader(JSON.Path+"/src/data/players.json");
JsonElement jsonElement = JsonParser.parseReader(reader);
JsonArray jsonArray = jsonElement.getAsJsonArray();
Queue<Players> players = new LinkedList<Players>();
for (JsonElement element : jsonArray) {
JsonObject jsonObject = element.getAsJsonObject();
String Country = "";
if (jsonObject.has("CountryName")) {
Country = jsonObject.get("CountryName").getAsString();
}
if (jsonObject.has("Participations")) {
JsonArray Participations = jsonObject.get("Participations").getAsJsonArray();
for (JsonElement participations : Participations) {
Players player=new Players();
player.setCountry(Country);
JsonObject childObject = participations.getAsJsonObject();
String FullName = childObject.get("PreferredLastName").getAsString()+" "+
childObject.get("PreferredFirstName").getAsString();
player.setFullName(FullName);
if(childObject.get("Gender").getAsInt() == 0) player.setGender("Male");
else player.setGender("Female");
//System.out.println(player);
players.offer(player);
}
}
}
int len = players.size();
Players[] player = new Players[len];
for(int i = 0;i < len;i++){
player[i]=players.poll();
}
Arrays.sort(player);
for(int i = 0;i < len;i++){
players.offer(player[i]);
}
reader.close();
return players;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
解析reuslt数据
public static Queue<Game> getGame(String file){
try {
// 创建Gson对象
Gson gson = new Gson();
// 读取json文件
Reader reader = new FileReader("src/data/"+file+".json");
JsonElement jsonElement = JsonParser.parseReader(reader);
JsonObject jsonObject = jsonElement.getAsJsonObject();
Queue<Game> games = new LinkedList<Game>();
if (jsonObject.has("Heats")) { //获取比赛
JsonArray Heats = jsonObject.get("Heats").getAsJsonArray();
for (JsonElement element : Heats) {
JsonObject match = element.getAsJsonObject();
if(match.get("Name").getAsString().equals("Final")){//判断是否为决赛
getMatch(match,games);
break;
}
}
}
return games;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
性能改进
对GetGameDetial函数进行改进,将原本采用队列循环获取数据的方法改为将队列转换为数组进行读取,减少了循环次数,避免数据反复存取。
单元测试
1.测试数据
Players
player
players
result
result detail
resultwomen 3m springboard
result men 10msynchronised
result women 10m synchronised details
result women 1m springboard
result women 3m springboard
result women 10m platform
result women 3m synchronised details
result women 10m synchronised
result men 1m springboard
result men 3m springboard details
result men 10m platform
result men 3m synchronised
result men 10m synchronised details
2.单元测试
public void testGetPlayers() {
Queue<Players> players = JSON.getPlayers();
String test = "Full Name:HART Alexander\n" +
"Gender:Male\n" +
"Country:Austria\n" +
"-----\n" +
"Full Name:LOTFI Dariush\n" +
"Gender:Male\n" +
"Country:Austria\n" +
"-----\n" +
"Full Name:SCHALLER Nikolaj\n" +
"Gender:Male\n" +
"Country:Austria\n" +
"-----\n" +
"Full Name:ABRAMOWICZ Tazman\n" +
"Gender:Male\n" +
"Country:Canada\n" +
"-----\n" +
"Full Name:BELANGER Eloise\n" +
"Gender:Female\n" +
"Country:Canada\n" +
"-----\n";
String player = "";
int i=0;
while (!players.isEmpty() && i < 5) {
player = player + players.poll().toString() + "\n-----\n";
i++;
}
Assert.assertEquals(test,player);
}
public void testGetGame() {
Queue<Game> games = JSON.getGame("women 3m springboard");
String test = "Full Name:BENT-ASHMEIL Desharne\n" +
"Rank:1\n" +
"Score:61.50 + 63.55 + 66.00 + 55.50 + 45.00 = 291.55\n" +
"-----\n" +
"Full Name:MULLER Jette\n" +
"Rank:2\n" +
"Score:63.00 + 63.00 + 61.50 + 40.30 + 60.00 = 287.80\n" +
"-----\n" +
"Full Name:HENTSCHEL Lena\n" +
"Rank:3\n" +
"Score:58.50 + 57.35 + 60.00 + 45.00 + 63.00 = 283.85\n" +
"-----\n" +
"Full Name:WILSON Aimee\n" +
"Rank:4\n" +
"Score:48.00 + 62.00 + 52.50 + 49.50 + 64.50 = 276.50\n" +
"-----\n" +
"Full Name:JASMIN Amelie-Laura\n" +
"Rank:5\n" +
"Score:63.00 + 57.40 + 51.00 + 54.00 + 51.00 = 276.40\n" +
"-----\n";
String game = "";
int i=0;
while (!games.isEmpty() && i < 5) {
game = game + games.poll().toString() + "\n-----\n";
i++;
}
Assert.assertEquals(test, game);
}
public void testGetGameDetial() {
Queue<GameDetial> gameDetails = JSON.getGameDetial("women 3m springboard");
String test = "Full Name:HENTSCHEL Lena\n" +
"Rank:1 | 4 | 3\n" +
"PreliminaryScore:54.00 + 63.55 + 48.00 + 60.00 + 51.00 = 276.55\n" +
"SemifinalScore:52.50 + 57.35 + 55.50 + 49.50 + 57.00 = 271.85\n" +
"FinalScore:58.50 + 57.35 + 60.00 + 45.00 + 63.00 = 283.85\n" +
"-----\n" +
"Full Name:MULLER Jette\n" +
"Rank:2 | 8 | 2\n" +
"PreliminaryScore:57.00 + 51.00 + 55.50 + 51.15 + 52.50 = 267.15\n" +
"SemifinalScore:57.00 + 51.00 + 55.50 + 31.00 + 54.00 = 248.50\n" +
"FinalScore:63.00 + 63.00 + 61.50 + 40.30 + 60.00 = 287.80\n" +
"-----\n" +
"Full Name:WILSON Aimee\n" +
"Rank:3 | 2 | 4\n" +
"PreliminaryScore:54.00 + 52.70 + 54.00 + 49.50 + 55.50 = 265.70\n" +
"SemifinalScore:52.50 + 55.80 + 57.00 + 52.50 + 58.50 = 276.30\n" +
"FinalScore:48.00 + 62.00 + 52.50 + 49.50 + 64.50 = 276.50\n" +
"-----\n" +
"Full Name:SKRZEK Kaja\n" +
"Rank:4 | 7 | 6\n" +
"PreliminaryScore:49.50 + 56.00 + 41.85 + 58.80 + 54.00 = 260.15\n" +
"SemifinalScore:49.50 + 50.40 + 55.80 + 46.20 + 48.00 = 249.90\n" +
"FinalScore:54.00 + 50.40 + 41.85 + 57.40 + 55.50 = 259.15\n" +
"-----\n" +
"Full Name:KESAR Viktoriya\n" +
"Rank:5 | 12 | 8\n" +
"PreliminaryScore:40.50 + 55.50 + 52.50 + 54.00 + 57.35 = 259.85\n" +
"SemifinalScore:54.00 + 58.50 + 27.00 + 31.50 + 54.25 = 225.25\n" +
"FinalScore:49.50 + 58.50 + 34.50 + 58.50 + 51.15 = 252.15\n" +
"-----\n";
String gameDetail = "";
int i=0;
while (!gameDetails.isEmpty() && i < 5) {
gameDetail = gameDetail + gameDetails.poll().toString() + "\n-----\n";
i++;
}
Assert.assertEquals(test, gameDetail);
}
异常处理
防止文件建立或读取失败,用catch捕捉错误并打印
try { // 防止文件建立或读取失败,用catch捕捉错误并打印
/* 读入TXT文件 */
File filename = new File(input_path); // 要读取以上路径的input.txt文件
InputStreamReader reader = new InputStreamReader(new FileInputStream(filename)); // 建立一个输入流对象reader
BufferedReader br = new BufferedReader(reader); // 建立一个对象,它把文件内容转成计算机能读懂的语言
String line = "";
line = br.readLine();
while (line != null) {
//line = line.replaceAll("\\s+"," ");//将多个空格变为一个空格
input.offer(line);
//System.out.println(line);
line = br.readLine(); // 一次读入一行数据
}
reader.close();
search(input,output);
/* 写入txt文件 */
File writename = new File(output_path); // 相对路径,如果没有则要建立一个新的output。txt文件
writename.createNewFile(); // 创建新文件
BufferedWriter out = new BufferedWriter(new FileWriter(writename));
while(!output.isEmpty()){
line=output.peek();
output.poll();
out.write(line+"\n");
out.flush(); // 把缓存区内容压入文件
}
out.close(); // 最后记得关闭文件
} catch (Exception e) {
e.printStackTrace();
}
心得体会
这次项目程序,让我学会了如何进行单元测试,使我对程序的结构以及类的划分方法有了更深的认识。