688
社区成员
发帖
与我相关
我的任务
分享软件工程实践第二次作业——个人实战
| 这个作业属于哪个课程 | 2023年福大-软件工程实践-W班 |
|---|---|
| 这个作业要求在哪里 | 软件工程实践第二次作业——个人实战 |
| 这个作业的目标 | 完成对澳大利亚网球公开赛相关数据的收集,并实现一个能够对赛事数据进行统计的控制台程序 |
| 其他参考文献 | CSDN上的多篇文章··· |
| PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | 20 | 30 |
| • Estimate | • 估计这个任务需要多少时间 | 50 | 60 |
| Development | 开发 | 600 | 600 |
| • Analysis | • 需求分析 (包括学习新技术) | 30 | 40 |
| • Design Spec | • 生成设计文档 | 30 | 40 |
| • Design Review | • 设计复审 | 20 | 30 |
| • Coding Standard | • 代码规范 (为目前的开发制定合适的规范) | 15 | 20 |
| • Design | • 具体设计 | 100 | 100 |
| • Coding | • 具体编码 | 40 | 30 |
| • Code Review | • 代码复审 | 30 | 30 |
| • Test | • 测试(自我测试,修改代码,提交修改) | 20 | 30 |
| Reporting | 报告 | 25 | 30 |
| • Test Repor | • 测试报告 | 15 | 20 |
| • Size Measurement | • 计算工作量 | 20 | 10 |
| • Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 25 |
| 合计 | 1035 | 1095 |
拿到这个实践作业后,看到这个作业要求语言选择Java和C++这两种语言二选一。但是推荐选择Java,并且我的感觉是Java语言也确实比C++语言要简单,所以我选择了Java。
拿到助教发的数据文件之后,发现是json类型的文件。通过上网寻找读取json文件的方法,最终选择了第三方Gson来读取文件进行编写代码。
发现助教给的文件并不全面,通过上网浏览,使用开发者工具把22号之后的数据爬取到data文件夹之中。
爬取内容如下:
以要读取的内容分为SearchPlayers类和SearchMatch类。然后要通过读取input.txt文件的内容,将内容输出output.txt文件中。这其中有涉及到IO的读取,对读取的内容进行代码逻辑运算,将结果最终输出到目标文件中。SearchPlayers类用来实现功能1:输出所有选手的信息;SearchMatch类用来实现功能2:输出正式赛每日结果及附加功能:输出资格赛结果。AOSearch类用于判断输入的指令是对应哪个功能,则调用对应类的方法。
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。
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();
}
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();
}
为了减少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();
}
}



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




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