代码:梁欢
评价:韩成玉
一、题目介绍
用户
小学、初中和高中数学老师。
功能
1、命令行输入用户名和密码,两者之间用空格隔开(程序预设小学、初中和高中各三个账号,具体见附表),如果用户名和密码都正确,将根据账户类型显示“当前选择为XX出题”,XX为小学、初中和高中三个选项中的一个。否则提示“请输入正确的用户名、密码”,重新输入用户名、密码;
2、登录后,系统提示“准备生成XX数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):”,XX为小学、初中和高中三个选项中的一个,用户输入所需出的卷子的题目数量,系统默认将根据账号类型进行出题。每道题目的操作数在1-5个之间,操作数取值范围为1-100;
3、题目数量的有效输入范围是“10-30”(含10,30,或-1退出登录),程序根据输入的题目数量生成符合小学、初中和高中难度的题目的卷子(具体要求见附表)。同一个老师的卷子中的题目不能与以前的已生成的卷子中的题目重复(以指定文件夹下存在的文件为准,见5);
4、在登录状态下,如果用户需要切换类型选项,命令行输入“切换为XX”,XX为小学、初中和高中三个选项中的一个,输入项不符合要求时,程序控制台提示“请输入小学、初中和高中三个选项中的一个”,输入正确后,显示“”系统提示“准备生成XX数学题目,请输入生成题目数量”,用户输入所需出的卷子的题目数量,系统新设置的类型进行出题;
5、生成的题目将以“年-月-日-时-分-秒.txt”的形式保存,每个账号一个文件夹。每道题目有题号,每题之间空一行;
附表-1:账户、密码
账户类型 | 账户 | 密码 |
---|---|---|
小学 | 张三1 | 123 |
小学 | 张三1 | 123 |
小学 | 张三1 | 123 |
初中 | 李四1 | 123 |
初中 | 李四1 | 123 |
初中 | 李四1 | 123 |
高中 | 王五1 | 123 |
高中 | 王五1 | 123 |
高中 | 王五1 | 123 |
附表-2:小学、初中、高中题目难度要求
小学 | 初中 | 高中 | |
---|---|---|---|
难度要求 | +,-,*./ | 平方,开根号 | sin,cos,tan |
备注 | 只能有+,-,*./和() | 题目中至少有一个平方或开根号的运算符 | 题目中至少有一个sin,cos或tan的运算符 |
二、代码分析
1.User类
package personalproject; /** * 抽象类用户类 */ public abstract class User { protected String userName; //用户名 protected String passWord; //密码 protected int teacherType; //教师类型 }
功能:定义抽象用户类
2.Teacher类
{ Teacher(){}; /** * 构造函数赋值 * @param TeacherType0 * @param userName0 * @param password0 */ public Teacher(int TeacherType0,String userName0,String password0){ this.teacherType=TeacherType0; this.userName=userName0; this.passWord =password0; } /** * 教师类型赋值 * @param TeacherType0 */ public void setTeacherType(int TeacherType0){ this.teacherType =TeacherType0; } /** * 用户名赋值 * @param userName0 */ public void setUserName(String userName0){ this.userName=userName0; } /** * 密码赋值 * @param password0 */ public void setPassword(String password0){ this.passWord =password0; } /** * 获取teacherType * @return this.teacherType */ public int getTeacherType(){ return this.teacherType; } /** * 获取用户名 * @return this.userName */ public String getUserName(){ return this.userName; } /** * 获取密码 * @return this.passWord */ public String getPassword(){ return this.passWord; } }
功能:定义教师类并获取值
3.StaticMethod类
1 package personalproject; 2 import java.util.Random; 3 4 /** 5 * 静态方法 6 */ 7 public class StaticMethod { 8 public static String[] WriteSign=new String[]{"+","-","*","/","(",")","^2","√","sin","cos","tan"}; 9 10 /** 11 * 根据类型生成题目 12 * @param type 13 * @return String 14 */ 15 public static String generateQuestion(int type){ 16 if(type==1) 17 return generatePrimaryQuestion(); 18 if(type==2) 19 return generateJuniorQuestion(); 20 if(type==3) 21 return generateSeniorQuestion(); 22 23 return "error"; 24 } 25 26 /** 27 * 概率函数 1/X的概率 28 * @param X 29 * @return true或false 30 */ 31 public static Boolean probability(int X){ 32 Random rand2=new Random(); 33 int randNum2= rand2.nextInt(X); 34 if(randNum2==0) 35 return true; 36 else 37 return false; 38 } 39 40 /** 41 * 小学题目 42 * @return String 43 */ 44 public static String generatePrimaryQuestion(){ 45 Random rand=new Random(); 46 String question=""; 47 int randNum=0; //随机生成本题的运算符数量 48 while(randNum==0){ 49 randNum=rand.nextInt(5); 50 } 51 int operNum=randNum; 52 int bracket=(operNum>2)?(operNum-2):0; //括号数量 53 int leftBracket =0; //左括号 54 int flag0=0; 55 int temp1; 56 for(int i=0;i<operNum;i++) 57 { 58 if(probability(5)&&bracket>0) 59 { 60 question=question+"("; 61 leftBracket++; 62 bracket--; 63 flag0=1; 64 } 65 temp1=rand.nextInt(100)+1; //随机生成操作数[1,100] 66 question=question+temp1; 67 if(probability(5)&& leftBracket !=0&&flag0==0) //在操作数之后生成一个符号,是括号则根据条件判断是否写入 68 { 69 question=question+")"; 70 leftBracket--; 71 } 72 temp1=rand.nextInt(4); //随机生成+ - * / 73 question=question+WriteSign[temp1]; 74 } 75 temp1=rand.nextInt(100)+1; //随机生成操作数[1,100] 76 question=question+temp1; 77 for(int i = 0; i< leftBracket; i++) { //补全缺少的后括号 78 question=question+WriteSign[5]; 79 } 80 return question+"="; 81 } 82 83 /** 84 * 初中题目 85 * @return String 86 */ 87 public static String generateJuniorQuestion(){ 88 Random rand=new Random(); 89 String question=1+"、"; 90 int operNum= rand.nextInt(5)+1; 91 int bracket=(operNum>2)?(operNum-2):0; //括号数量 92 int leftBracket =0; //左括号 93 int flag0=0; //刚生成操作数前是否有左括号,防止“(操作数)” 94 int flag1=0; //是否已有平方或根号 95 int temp1; 96 for(int i=1;i<=operNum;i++) 97 { 98 if(probability(7)) //生成√,flag1=1; 99 { 100 question=question+"√"; 101 flag1=1; 102 } 103 if(probability(7)&&bracket>0) 104 { 105 question=question+"("; 106 leftBracket++; 107 bracket--; 108 flag0=1; 109 } 110 temp1=rand.nextInt(100)+1; //随机生成操作数[1,100] 111 question=question+temp1; 112 if(probability(7)&& leftBracket !=0&&flag0==0) //在操作数之后生成一个符号,是括号则根据条件判断是否写入 113 { 114 question=question+")"; 115 leftBracket--; 116 } 117 if(probability(7)&&flag1==0) //生成^2,flag1=1; 118 { 119 question=question+"^2"; 120 flag1=1; 121 } 122 if(i==operNum) break; 123 temp1=rand.nextInt(4); //随机生成+ - * / 124 question=question+WriteSign[temp1]; 125 flag0=0; 126 } 127 if(flag1==0){ 128 if(probability(2)) 129 question="√"+question; 130 else 131 question=question+"^2"; 132 } 133 for(int i = 0; i< leftBracket; i++) { //补全缺少的后括号 134 question=question+WriteSign[5]; 135 } 136 return question+"="; 137 } 138 139 /** 140 * 高中题目 141 * @return String 142 */ 143 public static String generateSeniorQuestion(){ 144 Random rand=new Random(); 145 String question=""; 146 int randNum=rand.nextInt(5)+1; 147 int bracket=(randNum >2)?(randNum -2):0; //括号数量 148 int leftBracket =0; //左括号 149 int flag0=0; //刚生成操作数前是否有左括号,防止“(操作数)” 150 int flag2=0; //是否已有三角函数 151 int temp1; 152 for(int i = 1; i<= randNum; i++) 153 { 154 temp1=rand.nextInt(11); //可能生成sin,cos,tan 155 if(temp1>=8){ 156 question=question+WriteSign[temp1]; 157 flag2=1; 158 } 159 if(probability(7)&&bracket>0) 160 { 161 question=question+"("; 162 leftBracket++; 163 bracket--; 164 flag0=1; 165 } 166 temp1=rand.nextInt(100)+1; //随机生成操作数[1,100] 167 question=question+temp1; 168 if(probability(7)&& leftBracket !=0&&flag0==0) //在操作数之后生成一个符号,是括号则根据条件判断是否写入 169 { 170 question=question+")"; 171 leftBracket--; 172 } 173 if(i== randNum) break; 174 temp1=rand.nextInt(4); //随机生成+ - * / 175 question=question+WriteSign[temp1]; 176 flag0=0; 177 } 178 if(flag2==0){ 179 temp1=rand.nextInt(3)+8; //未生成三角函数,在最前面生成sin,cos,tan 180 question=WriteSign[temp1]+question; 181 } 182 for(int i = 0; i< leftBracket; i++) { //补全缺少的后括号 183 question=question+WriteSign[5]; 184 } 185 return question+"="; 186 } 187 }
功能:该类主要包含了生成运算符号和三种年级的题目的方法,其中每个年级的题目生成算法都不同。
4.QuestionSystem类
package personalproject; import static personalproject.StaticMethod.generateQuestion; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Scanner; /** * 出题系统类 * * @author Penguin * @version jdk17.0.4 */ public class QuestionSystem { private File f0 = new File("."); private String filePath0 = f0.getAbsolutePath(); private String filePath = filePath0.substring(0, filePath0.length() - 1); + "test"; //文件保存路径 private String userName; //用户名 private String passWord; //密码 private int type; //当前类型 private List<Teacher> userList = new ArrayList<Teacher>(); //所有保存所有用户信息 public boolean isLogin = false; //检查是否已经成功登录 /** *构造函数,将所有用户信息导入保存在链表 */ public QuestionSystem() { try { FileReader usertxt = new FileReader(filePath+"\\user.txt"); BufferedReader bf0 = new BufferedReader(usertxt); String s; while ((s = bf0.readLine()) != null) { String[] str = s.split("\\s+"); if (str[0].equals("小学")) { this.type = 1; } if (str[0].equals("初中")) { this.type = 2; } if (str[0].equals("高中")) { this.type = 3; } this.userName = str[1]; this.passWord = str[2]; Teacher T=new Teacher(this.type,this.userName,this.passWord); this.userList.add(T); } bf0.close(); }catch(Exception e){ e.printStackTrace(); } } public boolean getIsLogin(){ return this.isLogin; } public int getType(){ return this.type; } public String getFilePath(){ return this.filePath; } /** * 登录 */ public void Login(){ System.out.println("请输入您的用户名和密码"); Scanner cin = new Scanner(System.in); String[ ] str = cin.nextLine().split("\\s+"); this.userName = str[0]; this.passWord = str[1]; System.out.println("确认登录Y或取消N"); String C=cin.nextLine(); if(C.equals("N")) return; for(Teacher T:this.userList){ if(!(T.getUserName().equals(userName))||!(T.getPassword().equals(passWord))) { System.out.println("您输入的用户名或密码错误请重新输入"); System.out.println(T.getUserName()); System.out.println(userName); System.out.println(T.getPassword()); System.out.println(passWord); return; } } isLogin =true; } /** * 生成试卷 * @param Y * @throws IOException * @throws URISyntaxException */ public void GenerateTestQuestions(int Y) throws IOException, URISyntaxException { File testfile=new File(filePath+"\\tempName.txt"); try { boolean b=testfile.createNewFile(); }catch(IOException e) { e.printStackTrace(); return; } for(int i=0;i<Y;i++) { String question=generateQuestion(this.type); //随机生成一道题目 if(Check(question)){ try{ FileWriter writer=new FileWriter(filePath+"\\tempName.txt"); writer.write(question+"\n"); writer.write("\n"); writer.close(); }catch(IOException e) { e.printStackTrace(); return; } } } String time = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date().getTime()); boolean b=testfile.renameTo(new File(filePath+"\\"+time+".txt")); System.out.println("题目已成功生成并保存在"+filePath+"\\"+time+".txt"); } /** * 查重 * @param question * @return 重复则true反之则false */ public Boolean Check(String question){ //File f=new File("D:\\Proj1\\"+userName); File f=new File(filePath); String tempstr; String[] files = f.list(); //返回文件夹下所有文件名 assert files != null; for (String str: files) { try { FileReader fr = new FileReader(filePath+"\\"+str); BufferedReader bf = new BufferedReader(fr); while ((tempstr = bf.readLine()) != null){ if(str.equals(question)) { return false; } } bf.close(); fr.close(); } catch (IOException e) { e.printStackTrace(); } } return true; } public void SwitchType(){ System.out.println("请选择小学、初中和高中三个选项中的一个"); Scanner cin=new Scanner(System.in); String intype=cin.nextLine(); if(intype.equals("小学")){ this.type=1; } else if(intype.equals("初中")){ this.type=2; } else if(intype.equals("高中")){ this.type=3; } } public void Quit(){ System.out.println("您已退出,请重新登录"); isLogin =false; } }
功能:该类主要包括用户界面生成,试卷生成,查重,文件读写这几类功能。
三、结果展示
以下为实际效果展示
可以看到结果正常。