结对编程之个人项目代码互评
2022/9/14 14:19:04
本文主要是介绍结对编程之个人项目代码互评,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
结对编程之个人项目代码互评
简介
这篇文章是我的结对编程搭档刘正豪——豪神的个人项目代码的总结评价。
豪神使用Java语言实现中小学数学卷子自动生成程序的预期功能,代码结构清晰,其中的某些函数不乏亮点。
项目需求
- 针对小学、初中和高中数学老师为主体用户的程序
- 要完成的功能有:
- 命令行输入用户名和密码进行登录,两者用空格隔开。
- 登录成功显示用户可生成的题目类型,可以输入所需的题目数量(限制在10-30之间),若输入-1可以退出当前登录并重新登录。
- 生成的题目保存到目标用户名文件中并以"年-月-日-时-分-秒.txt"的形式保存,每个用户名一个文件夹,每道题目以(+题号+)开头并且每题之间要空一行,同一账号生成的题目不允许和已生成的题目重复。
- 用户可以在任何时刻输入“切换为”+类型切换到指定教师类型,同时具备该类型老师的出题资格。
- 备注:
- 预制账户:
账户类型 用户名 密码 小学 张三1 123 小学 张三2 123 小学 张三3 123 初中 李四1 123 初中 李四2 123 初中 李四3 123 高中 王五1 123 高中 王五2 123 高中 王五3 123 - 题目要求:
小学 初中 高中 难度要求 +,-,*./ 平方、开方 sin,cos,tan 备注 只能有+,-,*./和() 题目中至少有一个平方或开根号的运算符 题目中至少有一个sin,cos或tan的运算符
- 预制账户:
代码结构
USer
由于代码全部复制过来太多,只说几个关键的。
public class User { private String id; private String psw; private String type; private boolean convert; @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } User user = (User) o; return id.equals(user.id) && psw.equals(user.psw); } @Override public int hashCode() { return Objects.hash(id, psw); } }
成员属性有4个,convert用于判断后续的是否重新登录的判断。
equals()函数用于登录时的判断
hashCode()函数用于后续查重
Login
剩余的代码都写在了Login里面,由于代码量较大,只展示其中几个关键的函数:
private void paper(int cnt,User u) throws IOException { Random r = new Random(); String[] specialSigns = {"?","√","sin","cos","tan"}; HashSet<String> hisQ = historyPaper(u); String path = "F:\\4\\Auto_Math\\out\\production\\Mathpaper\\" + u.getId() + "/"; Calendar date = Calendar.getInstance(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); String time = formatter.format(date.getTime()); path = path + time + ".txt"; //生成题目 FileWriter fw = new FileWriter(path,true); for(int i = 0;i < cnt;i++){ String question; //生成单个题目 question = singleQuestion(u, r, specialSigns); //查询是否与历史题目重复 if(hisQ.contains(question)){ i--; continue; } question = "第" + (i + 1) + "题: " + question + "="; fw.write(question+"\r\n"); } fw.close(); }
本次的关键是生成题目,先生成路径后生成题目,生成单个题目之后进行查重,最后输出到文件里,思路清晰,代码简洁。
private String singleQuestion(User u, Random r, String[] specialSigns) { String[] signs = {"+","-","×","÷"}; String question = null; String[] opQ = null; String type= u.getType(); switch (type){ case "小学" -> { int opNum = r.nextInt(4) + 2; opQ = new String[opNum]; for(int i = 0;i < opNum;i++){ opQ[i] = String.valueOf(r.nextInt(100) + 1); } //括号 addBracket(r, opQ, opNum); } case "初中" -> { int opNum = r.nextInt(5) + 1; opQ = new String[opNum]; for(int i = 0;i < opNum;i++){ opQ[i] = String.valueOf(r.nextInt(100) + 1); } //特殊符号数 int sopNum = r.nextInt(opNum) + 1; while((sopNum--) != 0){ int rPos = r.nextInt(opNum); if(!opQ[rPos].contains("?") && !opQ[rPos].contains("√")){ opQ[rPos]= r.nextBoolean()? opQ[rPos]+"?": "√"+opQ[rPos]; } } addBracket(r, opQ, opNum); } case "高中" -> { int opNum = r.nextInt(5) + 1; opQ = new String[opNum]; for(int i = 0;i < opNum;i++){ opQ[i] = String.valueOf(r.nextInt(100) + 1); } //特殊符号数 int sopNum = r.nextInt(opNum) + 1; boolean[] speOpFlag = new boolean[opNum]; //确保至少有一个三角函数 int tri = 0; while((sopNum--) != 0){ int rPos = r.nextInt(opNum); if(tri == 0 && !opQ[rPos].contains("sin") && !opQ[rPos].contains("cos") && !opQ[rPos].contains("tan")){ opQ[rPos] = specialSigns[r.nextInt(3)+2] + opQ[rPos]; tri++; speOpFlag[rPos] = true; } if(!speOpFlag[rPos]){ int rOp = r.nextInt(5); opQ[rPos] = rOp < 1 ? opQ[rPos] + specialSigns[rOp] : specialSigns[rOp] + opQ[rPos]; speOpFlag[rPos] = true; } } addBracket(r, opQ, opNum); } default -> System.out.println("error"); } assert opQ != null; for(int i = 0;i < opQ.length ;i++){ int opType = r.nextInt(4); question = (question == null?"":question) + (i!=0?signs[opType]:"") + opQ[i]; } return question; }
这是生成单个题目的函数,分为三类来进行。逻辑基本是差不多的,先通过随机数生成几个操作数,之后再利用循环判断添加操作符。
private void addBracket(Random r, String[] opQ, int opNum) { boolean bracket = r.nextBoolean() && opNum > 2; if(bracket){ int range = r.nextInt(opNum - 2) + 1; int left = r.nextInt(opNum - range); opQ[left] = "(" + opQ[left]; opQ[left+range] = opQ[left+range] + ")"; } }
括号是在算式最后添加的,通过随机数来确定位置。
private HashSet<String> historyPaper(User u) throws IOException { HashSet<String> hisQuestions = new HashSet<>(); String path = "F:\\4\\Auto_Math\\out\\production\\Mathpaper" + "\\" + u.getId(); File folder = new File(path); if(!folder.exists()){ folder.mkdir(); } File[] fList = folder.listFiles(); assert fList != null; for(File f : fList){ if (f.isFile() && f.getName().endsWith(".txt")){ BufferedReader br = new BufferedReader(new FileReader(f)); String s; while((s = br.readLine()) != null){ hisQuestions.add(s); } br.close(); } } return hisQuestions; }
对于题目查重,豪神采用了哈希表,将同一用户名文件夹下的题目导入哈希表中,挨个查询,这样做大大节省了查询的复杂度,好评!
优缺点分析
优点
- 因为我使用的C++,在我看来Java的代码更加的简洁,功能强大,同时不会出现编码上的问题,看的出来豪神的编程能力十分强力。
- 生成题目的方式和我相比非常的易于理解,同时不会出现看起来特别怪异的题目,思路比较清晰。
- 在查重时使用哈希表,非常的妙啊。
缺点
- 有些地方命名不是很规范,过于简单,同时有些地方欠缺一点注释,希望下次可以多一点。
- 初高中题目不够随机,可以有一些复杂符号的多重组合,折磨一下考生(bushi
- 比较主观的见解:可以分更多的类出来,而不是几乎全部写在其中一个类里面,让代码的复用性更好。
心得
Java还是非常好用的,要今后多学习Java的使用,很多都封装好了可以直接拿来用,不需要我再写了。多看看其他人的代码一方面可以让我学到更多的编程思路,学习其他人的切入点,另一方面通过检查他人代码的缺陷,我也能反省自身,不再犯类似的错误。
这篇关于结对编程之个人项目代码互评的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-04-26敏捷开发:想要快速交付就必须舍弃产品质量?
- 2024-04-26静态代码分析的这些好处,我竟然都不知道?
- 2024-04-26你在测试金字塔的哪一层?(下)
- 2024-04-26快刀斩乱麻,DevOps让代码评审也自动起来
- 2024-04-262024年最好用的10款ER图神器!
- 2024-04-2203-为啥大模型LLM还没能完全替代你?
- 2024-04-2101-大语言模型发展
- 2024-04-17基于SpringWeb MultipartFile文件上传、下载功能
- 2024-04-14个人开发者,Spring Boot 项目如何部署
- 2024-04-14RAG应用开发实战02-相似性检索的关键 - Embedding