结对编程队友代码分析
目录
一、整体思路
队友使用Java语言进行编程,并分为三个文件
文件名 | 主要功能 |
---|---|
User.java | 定义user类和用户登录log_in函数 |
Formula.java | createSingleFormula方法生成一个合法算式 |
Main.java | 主函数执行和辅助判断函数 |
二、重要的代码实现
1.顶层类设计
User类的设计用户名,用户类型
public class User {
private String userName;
private String userType;
public String getUserName() {
return userName;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType=userType;
}
}
其中userType用于多个地方,可以确定生成试卷的类型/切换试卷类型/题目难度设置
顶层类设计了登录方法log_in(),其中进行了while判断,并且可以复用该方法
/**
*
* @Title: LogIn()
* @Description: 用户登录,输入账户和密码, 错误时重新登录
* @return void
*/
public void LogIn() {
String inputNameString;
String inputPasswordString;
Boolean loginSuccessBoolean = false;
String path = "users.txt";
System.out.println("-----欢迎来到中小学数学卷子自动生成系统-----");
while (!loginSuccessBoolean) {
System.out.println("请输入正确的用户名、密码(中间用空格隔开)");
Scanner scanner = new Scanner(System.in);
String[] login_info = scanner.nextLine().split(" ");
if (login_info.length != 2) continue;
inputNameString = login_info[0];
inputPasswordString = login_info[1];
try (FileReader reader = new FileReader(path);
BufferedReader br = new BufferedReader(reader)) {
String txt_line;
while ((txt_line = br.readLine()) != null) {
String[] txt_info = txt_line.split(" ");
if (inputNameString.equals(txt_info[0])
&& inputPasswordString.equals(txt_info[1])) {
System.out.println("当前选择为" + txt_info[2] + "出题");
userName = txt_info[0];
userType = txt_info[2];
loginSuccessBoolean = true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
String testType = userType;
System.out.println("/n"+"准备生成" + testType + "数学题目,请输入生成题目数量(10-30)(输入-1将退出当前用户,重新登录)");
System.out.println("/n"+"如需模式切换,请输入/"切换为小学/",/"切换为初中/",/"切换为高中/"");
}
2.生成合法算式
队友生成合法算式的思路如下:
首先将x个操作数和操作符依次加入List
// 首先将操作数和操作符依次加入res列表
for (int i = 1; i <= oprandNum; i++) {
res.add(Integer.toString(rand.nextInt(100) + 1));
if (i != oprandNum) {
Integer dice = rand.nextInt(4);
res.add(fourOption[dice]);
}
else res.add("=");
}
然后列出2-5个操作数范围内,所有括号可能出现的位置
private Integer[][] bracketPosition =
{{0, 2}, {2, 4}, {4, 6}, {0, 4}, {2, 6}, {0, 6}, {2, 8}, {4, 8}, {6, 8}};
在已知操作数个数的情况下,括号可能出现的位置种类是确定的
此时随机选择一组括号加入表达式,并判断括号的合法性,如有交叉,不合法
for (List<Integer> opt : bracketOption) {
if (opt.get(1) >= bracketDice[0] && opt.get(1) < bracketDice[1]
&& opt.get(0) < bracketDice[0])
legal = false;
else if (opt.get(1) > bracketDice[1] && opt.get(0) <= bracketDice[1]
&& opt.get(0) > bracketDice[0])
legal = false;
else if (opt.get(1).equals(bracketDice[1]) && opt.get(0).equals(bracketDice[0])) {
legal = false;
}
}
3.满足初高中题目要求
// 判断是否符合初中要求
if (paperType.equals("初中")) {
Boolean middleLimit = false;
for (int i = 0; i < res.size(); i++) {
if (i % 2 == 0 && rand.nextInt(2) == 1) {
if (rand.nextInt() % 2 == 0)
res.set(i, middleOption[0] + res.get(i));
else
res.set(i, res.get(i) + middleOption[1]);
middleLimit = true;
}
}
if (!middleLimit)
res.set(res.size() - 2, res.get(res.size() - 2) + middleOption[1]);
}
// 判断是否符合初中要求
if (paperType.equals("高中")) {
Boolean highLimit = false;
for (int i = 0; i < res.size(); i++) {
if (i % 2 == 0 && rand.nextInt(2) == 1) {
Integer tri_dice = rand.nextInt(3);
res.set(i, highOption[tri_dice] + "(" + res.get(i) + ")");
highLimit = true;
}
}
if (!highLimit)
res.set(res.size() - 2,
highOption[rand.nextInt(3)] + "(" + res.get(res.size() - 2) + ")");
}
4.多文件去重和单文件去重
首先要得到该用户文件夹下所有生成的文件,并且储存到Hash
/**
* @param
* @return HashSet<String>
* @Title: getUsedProblem()
* @Description: 得到当前用户文件夹下所有题目
*/
public static HashSet<String> getUsedProblem(User loginTest) {
String path = loginTest.getUserName();
// 获取路径下所有file对象
File file = new File(path);
// 遍历path下的文件和目录,放在fs数组中
File[] fs = file.listFiles();
HashSet<String> UsedProblem = new HashSet<String>();
// 将所有算式添加到HashSet<string>
for (File f : fs) {
if (!f.isDirectory()) {
try {
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null) {
UsedProblem.add(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return UsedProblem;
}
然后主函数的判断中:每生成一个式子,都要和当前文件与之前文件的式子查重
String nowques = formula.createSingleFormula(loginTest);
HashSet<String> used = getUsedProblem(loginTest);
HashSet<String> now_paper = new HashSet<String>();
while (used.contains(nowques) || now_paper.contains(nowques))
nowques = formula.createSingleFormula(loginTest);
5.Java的工具清屏类
java的内置console类并不能像c++的cmd里直接清屏,需要一些特殊的方法,队友利用了java的机器人来清屏,很有趣。
/**
* @return void
* @throws AWTException
* @Title: clear()
* @Description: java机器人类,实现清屏
*/
public static void clear() throws AWTException {
Robot r = new Robot();
r.mousePress(InputEvent.BUTTON3_MASK);
r.mouseRelease(InputEvent.BUTTON3_MASK);
r.keyPress(KeyEvent.VK_CONTROL);
r.keyPress(KeyEvent.VK_R);
r.keyRelease(KeyEvent.VK_R);
r.keyRelease(KeyEvent.VK_CONTROL);
r.delay(100);
}
三.程序运行实际情况
整体流程还算完整,对于错误输出有一定限制,可以达到脸滚键盘随意输入测试后,程序可以给出引导语而不会崩溃。
四.优缺点
1.优点
用户的需求成功满足;
多个括号嵌套生成并且合法
纠错功能避免溢出,允许用户的非法输入。
2.缺点
程序较为分散,阅读起来函数调用有一点难懂。
if语句太多,代码的复用性不强。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/289300.html