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

062000507郭河源 学生 2023-03-03 23:56:27

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

这个作业属于哪个课程2023年福大-软件工程实践-W班
这个作业要求在哪里软件工程实践第二次作业——个人实战
这个作业的目标完成对澳大利亚网球公开赛相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序
其他参考文献CSDN上的多篇文章···

目录

  • 一、GitCode项目地址
  • 二、PSP表格
  • 三、解题思路描述
  • 3.1开发语言选择
  • 3.2数据读取
  • 3.3数据爬取
  • 四、接口设计和实现过程
  • 4.1接口设计
  • 4.2实现过程
  • 五、关键代码展示
  • 5.1 读取players.json文件的内容并输出
  • 5.2读取日期文件并输出
  • 5.3
  • 六、程序性能改进
  • 6.1性能改进
  • 七、单元测试
  • 八、异常处理
  • 8.1异常输入input.txt
  • 8.2异常输出output.txt
  • 九、心路历程与收获


一、GitCode项目地址

062000507_郭河源/ Project-Java

二、PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2030
• Estimate• 估计这个任务需要多少时间5060
Development开发600600
• Analysis• 需求分析 (包括学习新技术)3040
• Design Spec• 生成设计文档3040
• Design Review• 设计复审2030
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)1520
• Design• 具体设计100100
• Coding• 具体编码4030
• Code Review• 代码复审3030
• Test• 测试(自我测试,修改代码,提交修改)2030
Reporting报告2530
• Test Repor• 测试报告1520
• Size Measurement• 计算工作量2010
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划2025
合计10351095

三、解题思路描述

3.1开发语言选择

拿到这个实践作业后,看到这个作业要求语言选择Java和C++这两种语言二选一。但是推荐选择Java,并且我的感觉是Java语言也确实比C++语言要简单,所以我选择了Java。

3.2数据读取

拿到助教发的数据文件之后,发现是json类型的文件。通过上网寻找读取json文件的方法,最终选择了第三方Gson来读取文件进行编写代码。

3.3数据爬取

发现助教给的文件并不全面,通过上网浏览,使用开发者工具把22号之后的数据爬取到data文件夹之中。
爬取内容如下:

alt

四、接口设计和实现过程

4.1接口设计

以要读取的内容分为SearchPlayers类和SearchMatch类。然后要通过读取input.txt文件的内容,将内容输出output.txt文件中。这其中有涉及到IO的读取,对读取的内容进行代码逻辑运算,将结果最终输出到目标文件中。SearchPlayers类用来实现功能1:输出所有选手的信息;SearchMatch类用来实现功能2:输出正式赛每日结果及附加功能:输出资格赛结果。AOSearch类用于判断输入的指令是对应哪个功能,则调用对应类的方法。

4.2实现过程

SeachPlayers使用InputStreamReader读取players.json文件的全部内容,先创建一个Jsonobject的data对象,在创建一个medalsList来存储json文件中的players数组内容。然后读取直接输出
SearchMatch使用InputStreamReader读取data.json文件的全部内容,日期比赛内容读取的比较麻烦。要先读取Schedule里的获胜队的team_id,然后再到teams里面通过寻找相同的team_id来确定players。但是此时的players是一个或多个字符串。所以使用vector来存储players的信息。接着直接到players里面寻找字符串相同的,然后输出short_time。

五、关键代码展示

5.1 读取players.json文件的内容并输出

public static String SearchPlayers() {
JsonParser parse = new JsonParser();//创建json解析器
StringBuilder strOut=new StringBuilder();
try {
InputStreamReader inpStrReader=new InputStreamReader(new FileInputStream("src/data/players.json"),"UTF-8");
JsonObject json = (JsonObject) parse.parse(inpStrReader);
String gender=null;
JsonObject data=json.getAsJsonObject();//jsonobject对象
JsonArray medalsList=data.get("players").getAsJsonArray(); //json数组
for(int i=0;i<medalsList.size();i++) {
JsonObject medal=medalsList.get(i).getAsJsonObject();
strOut.append("full_name"+":"+medal.get("full_name").getAsString()+"\n");
switch (medal.get("gender").getAsString()){
case "M":
gender = "male";
break;
case "F":
gender = "female";
break;
default:
gender = "other";
}
strOut.append("gender"+":"+gender+"\n");
strOut.append("nationality"+":"+medal.get("nationality").getAsJsonObject().get("name").getAsString()+"\n");
strOut.append("-----"+"\n");
}
} catch (JsonIOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonSyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("文件未找到...");
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return strOut.toString();
}

5.2读取日期文件并输出

public static String SearchMatch(String date) {
JsonParser parse = new JsonParser();//创建json解析器
StringBuilder strOut = new StringBuilder();
try {
InputStreamReader inpStrReader = new InputStreamReader(new FileInputStream("src/data/" + date + ".json"), "UTF-8");
JsonObject json = (JsonObject) parse.parse(inpStrReader);
JsonObject data = json.get("schedule").getAsJsonObject();
JsonArray matchList = data.get("courts").getAsJsonArray();
Vector players=new Vector<>();
String team_id=null;
JsonArray teamsList = json.get("teams").getAsJsonArray();
JsonArray playerList = json.get("players").getAsJsonArray();
for (int i = 0; i < matchList.size(); i++) {
JsonObject array = matchList.get(i).getAsJsonObject();
if (!(array.get("sessions") != null) || array.get("sessions").getAsJsonArray().size() == 0)
{
continue;
}
JsonArray matchList1 = array.get("sessions").getAsJsonArray();
for (int x = 0; x < matchList1.size(); x++) {
JsonObject array1 = matchList1.get(x).getAsJsonObject();
if (!(array1.get("activities") != null) || array1.get("activities").getAsJsonArray().size() == 0)
{
continue;
}
JsonArray matchList2 = array1.get("activities").getAsJsonArray();
for (int y = 0; y < matchList2.size(); y++) {
JsonObject array2 = matchList2.get(y).getAsJsonObject();
if (!(array2.get("teams") != null) || array2.get("teams").getAsJsonArray().size() == 0)
{
continue;
}
JsonArray matchList3 = array2.get("teams").getAsJsonArray();
if (array2.get("match_status") != null && array2.get("match_status").getAsJsonObject().get("abbr") != null && array2.get("match_status").getAsJsonObject().get("abbr").getAsString().equals("W/O"))
{
strOut.append("W/O" + "-----" + "\n");
}
if (array2.get("actual_start_time") == null) {
continue;
} else {
strOut.append("time" + ":" + array2.get("actual_start_time").getAsString() + "\n");
}
for (int z = 0; z < matchList3.size(); z++) {
JsonObject array3 = matchList3.get(z).getAsJsonObject();
if ((array3.get("status") != null) && (array3.get("status").getAsString().equals("Winner"))) {
team_id = array3.get("team_id").getAsString();
for (int t = 0; t < teamsList.size(); t++) {
JsonObject team = teamsList.get(t).getAsJsonObject();
if (team_id.equals(team.get("uuid").getAsString())) {
for (int m = 0; m < team.get("players").getAsJsonArray().size(); m++) {
players.add(team.get("players").getAsJsonArray().get(m).getAsString());
}
}
}
for (int a = 0; a < playerList.size(); a++) {
JsonObject player1 = playerList.get(a).getAsJsonObject();
for (int m = 0; m < players.size(); m++) {
if (players.get(m).equals(player1.get("uuid").getAsString())) {
if (m == players.size() - 1) {
strOut.append(player1.get("short_name").getAsString() + "\n");
} else {
strOut.append(player1.get("short_name").getAsString() + "&");
}
}
}
}
}
StringBuilder s = new StringBuilder();
for (int n = 0; n < matchList3.get(0).getAsJsonObject().get("score").getAsJsonArray().size(); n++) {
if (n == matchList3.get(0).getAsJsonObject().get("score").getAsJsonArray().size() - 1) {
s.append(matchList3.get(0).getAsJsonObject().get("score").getAsJsonArray().get(n).getAsJsonObject().get("game").getAsString()).append(":");
s.append(matchList3.get(1).getAsJsonObject().get("score").getAsJsonArray().get(n).getAsJsonObject().get("game").getAsString());
} else {
s.append(matchList3.get(0).getAsJsonObject().get("score").getAsJsonArray().get(n).getAsJsonObject().get("game").getAsString()).append(":");
s.append(matchList3.get(1).getAsJsonObject().get("score").getAsJsonArray().get(n).getAsJsonObject().get("game").getAsString()).append(" | ");
}
}
strOut.append(s + "\n");
strOut.append("-----" + "\n");
}
}
}
}
System.out.println(strOut);
}catch(JsonIOException e){
// TODO Auto-generated catch block
e.printStackTrace();
} catch(JsonSyntaxException e){
// TODO Auto-generated catch block
e.printStackTrace();
} catch(FileNotFoundException e){
// TODO Auto-generated catch block
System.out.println("文件未找到...");
e.printStackTrace();
} catch(UnsupportedEncodingException e){
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return strOut.toString();
}

5.3

六、程序性能改进

6.1性能改进

为了减少IO提高性能,文件操作直接在AOSearch处理
public static void DealOrder(ArrayList orders,String pathOutput) {
try {
File file=new File(pathOutput);
if(!file.exists()) {//文件不存在
file.createNewFile();
}
Writer outTxt = new OutputStreamWriter(new FileOutputStream(file,true), "utf-8");
BufferedWriter buffoutTxt=new BufferedWriter(outTxt);
for(int i=0;i<orders.size();i++) {//对每一条指令
if(i==orders.size()-1) isLast=true;
String[] ss= orders.get(i).split("\s+");//切开空格
if(ss.length==1 && ss[0].equals("players")) {//指令1:total
if(data.containsKey(ss[0])) {//在缓存中
if(isLast) buffoutTxt.write(data.get(ss[0]).trim());
else buffoutTxt.write(data.get(ss[0]));
//Lib.Write(data.get(ss[0]), isLast);
//Lib.Write("我在缓存中", isLast);
}
else {//不在缓存中
data.put(ss[0], Tool.SearchPlayers());
if(isLast) buffoutTxt.write(Tool.SearchPlayers().trim());
else buffoutTxt.write(Tool.SearchPlayers());
//Lib.Write(Lib.MedalsTotal(),isLast);
//data.put(ss[0], Lib.MedalsTotal());
}
}
else if(ss.length==2 && ss[0].equals("result")) {//指令2: xxxx
try {
String date=ss[1];
if((date.equals("0116"))||(date.equals("0117"))||(date.equals("0118"))||(date.equals("0119"))||(date.equals("0120"))
||(date.equals("0121"))||(date.equals("0122"))||(date.equals("0123"))||(date.equals("0124"))||(date.equals("0125"))
||(date.equals("0126"))||(date.equals("0127"))||(date.equals("0128"))||(date.equals("0129"))) {
if(data.containsKey(ss[1])) {
if(isLast) buffoutTxt.write(data.get(ss[1]).trim());
else buffoutTxt.write(data.get(ss[1]));
//Lib.Write(data.get(ss[1]), isLast);//在缓存中
}
else {//不在缓存中
data.put(ss[1], Tool.SearchMatch(ss[1]));
if(isLast) buffoutTxt.write(Tool.SearchMatch(ss[1]).trim());
else buffoutTxt.write(Tool.SearchMatch(ss[1]));
//Lib.Write(Lib.MedalsSchedule(ss[1]),isLast);
//data.put(ss[1], Lib.MedalsSchedule(ss[1]));
}
}
else {//xxxx日期不在范围内
if(isLast) buffoutTxt.write("N/A"+"\n"+"-----");
else buffoutTxt.write("N/A"+"\n"+"-----"+"\n");
//Lib.Write("N/A"+"\n",false);
//Lib.Write("-----"+"\n",isLast);
}
}catch(NumberFormatException e) {//xxxx日期不是数字
String date=ss[1];
if((date.equals("Q1"))||(date.equals("Q2"))||(date.equals("Q3"))||(date.equals("Q4"))) {
if(data.containsKey(ss[1])) {
if(isLast) buffoutTxt.write(data.get(ss[1]).trim());
else buffoutTxt.write(data.get(ss[1]));
//Lib.Write(data.get(ss[1]), isLast);//在缓存中
}
else {//不在缓存中
data.put(ss[1], Tool.SearchMatch(ss[1]));
if(isLast) buffoutTxt.write(Tool.SearchMatch(ss[1]).trim());
else buffoutTxt.write(Tool.SearchMatch(ss[1]));
//Lib.Write(Lib.MedalsSchedule(ss[1]),isLast);
//data.put(ss[1], Lib.MedalsSchedule(ss[1]));
}
}
else {//xxxx日期不在范围内
if(isLast) buffoutTxt.write("N/A"+"\n"+"-----");
else buffoutTxt.write("N/A"+"\n"+"-----"+"\n");
//Lib.Write("N/A"+"\n",false);
//Lib.Write("-----"+"\n",isLast);
}
}
}
else if(ss.length==1 && ss[0].equals("")) {//指令3:空指令(不处理,跳过)
//System.out.println("空");
}
else if(ss[0].equals("result") && ss.length>1) {
if(isLast) buffoutTxt.write("N/A"+"\n"+"-----");
else buffoutTxt.write("N/A"+"\n"+"-----"+"\n");
}
else {//4:无法识别的其它指令
if(isLast) buffoutTxt.write("Error"+"\n"+"-----");
else buffoutTxt.write("Error"+"\n"+"-----"+"\n");
//Lib.Write("Error"+"\n",false);
//Lib.Write("-----"+"\n",isLast);
}
}
buffoutTxt.close();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

七、单元测试

alt

八、异常处理

8.1异常输入input.txt

alt

8.2异常输出output.txt

alt

九、心路历程与收获

这个第二次软件实践作业,对于我这个代码能力奇差的人来说,是真的折磨。花费了好几天时间,好不容易把这些功能和接口实现,然后后面发现那个相对路径和绝对路径的问题(之前相对路径一直不行,为了后面代码功能的完善,我就先用绝对路径来替代相对路径),来不及了。真的是折磨,上网查了好久的时间,很奇怪为什么我这边相对路径不能行,但又不是代码的问题(因为绝对路径都能运行)。查了好久,也问了好久,最后得出一个结论:IDEA的maven模块的相对路径,必须要加上模块名。但是这样的话,jar文件在命令行中就无法运行。一直到最后这个问题我都不知道怎么解决。还有那个单元测试,查了好久,后面用junit来进行单元测试,也在参数输入那边被卡住了(也是路径的问题)。实在没办法,我就只能手动把所有json文件都读取运行了一遍,只能确定我的代码功能是没有问题的。
总的来说,写了好久的代码,花了好久的时间。本来对json文件的读取一无所知,时间的大头一开始也是花费在这里,查了好久的资料,打了好久的代码,才最终能运行。但是我的代码本来就不行,到了后面日期的逻辑循环,还有各种各样的报错。都已经习惯了在电脑面前打开一堆CSDN,感觉收获还是挺大的。然后后面由于宿舍里有一个“再生父母”在,最后一秒,终于把这些都搞定了,而且命令行也能运行,真的是完美了hh。

...全文
247 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
郭渊伟 2023-03-11
  • 打赏
  • 举报
回复

注意代码风格,提升可读性

062000507郭河源 学生 2023-03-04
  • 打赏
  • 举报
回复

emmm,就是用命令行运行jar文件的时候,你要输入你读的文件的绝对路径,然后输出你读出文件的名字(例如output.txt),输出文件的路径不用写,只写个文件名就可以了。单元测试的话写个单元测试类AOSearchTest。你在new一个AOSearch的时候跟命令行输入一样,要写你要输入文件的绝对路径,然后写一个你要输出的文件名字(代码会判断这个文件是否存在,若无,则创建一个新的文件)。至于前面的绝对和相对路径,是我之前运行代码的时候魔怔了

img

img

img

img


总的来说,路径问题只是我一直注意着源代码的环境,没考虑到jar的运行环境,一时间愣住了。思维没转变过来,幸亏后面舍友的提醒,才令我及时醒悟

SoftwareTeacher 2023-03-04
  • 打赏
  • 举报
回复

一直到最后这个问题我都不知道怎么解决。还有那个单元测试,查了好久,后面用junit来进行单元测试,也在参数输入那边被卡住了(也是路径的问题)。


请把解决的方法写出来吧!

688

社区成员

发帖
与我相关
我的任务
社区描述
2023年福州大学软件工程实践课程W班的教学社区
软件工程团队开发软件构建 高校 福建省·福州市
社区管理员
  • FZU_SE_teacherW
  • 张书旖
  • 郭渊伟
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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