一、前言
本次博客是对“中小学数学试卷自动生成程序”的个人项目的互评,编程语言都是java.
二、代码需求
个人项目:中小学数学卷子自动生成程序
用户:
小学、初中和高中数学老师。
功能:
1、命令行输入用户名和密码,两者之间用空格隔开(程序预设小学、初中和高中各三个账号,具体见附表),如果用户名和密码都正确,将根据账户类型显示“当前选择为XX出题”,XX为小学、初中和高中三个选项中的一个。否则提示“请输入正确的用户名、密码”,重新输入用户名、密码;
2、登录后,系统提示“准备生成XX数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):”,XX为小学、初中和高中三个选项中的一个,用户输入所需出的卷子的题目数量,系统默认将根据账号类型进行出题。每道题目的操作数在1-5个之间,操作数取值范围为1-100;
3、题目数量的有效输入范围是“10-30”(含10,30,或-1退出登录),程序根据输入的题目数量生成符合小学、初中和高中难度的题目的卷子(具体要求见附表)。同一个老师的卷子中的题目不能与以前的已生成的卷子中的题目重复(以指定文件夹下存在的文件为准,见5);
4、在登录状态下,如果用户需要切换类型选项,命令行输入“切换为XX”,XX为小学、初中和高中三个选项中的一个,输入项不符合要求时,程序控制台提示“请输入小学、初中和高中三个选项中的一个”;输入正确后,显示“”系统提示“准备生成XX数学题目,请输入生成题目数量”,用户输入所需出的卷子的题目数量,系统新设置的类型进行出题;
5、生成的题目将以“年-月-日-时-分-秒.txt”的形式保存,每个账号一个文件夹。每道题目有题号,每题之间空一行;
6、个人项目9月17日晚上10点以前提交至创新课程管理系统。提交方式:工程文件打包,压缩包名为“几班+姓名.rar”。迟交2天及以内者扣分,每天扣20%。迟交2天及以上者0分。
附表-1:账户、密码
账户类型 |
账户 |
密码 |
备注 |
小学 |
张三1 |
123 |
|
张三2 |
123 |
|
|
张三3 |
123 |
|
|
初中 |
李四1 |
123 |
|
李四2 |
123 |
|
|
李四3 |
123 |
|
|
高中 |
王五1 |
123 |
|
王五2 |
123 |
|
|
王五3 |
123 |
|
附表-2:小学、初中、高中题目难度要求
|
小学 |
初中 |
高中 |
|
难度要求 |
+,-,*./ |
平方,开根号 |
sin,cos,tan |
|
备注 |
只能有+,-,*./和() |
题目中至少有一个平方或开根号的运算符 |
题目中至少有一个sin,cos或tan的运算符 |
|
三、功能测试
测试环境:Eclipse IDE 2022
测试过程:
输入错误的账号密码之后会自动退出,重新进入输入正确的账号密码登录进去就可以正常出题了。
下面展示的是出的小学题目:
然后登陆初中账号,展示初中题目:
然后登陆高中账号,展示高中题目:
四、代码分析
1.整体结构,分了4个包,
2.具体代码内容:
这个是system包里面的Generator类。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package system; 2 3 import java.io.IOException; 4 import java.util.Scanner; 5 import teacher.JuniorTeacher; 6 import teacher.PrimaryTeacher; 7 import teacher.SeniorTeacher; 8 9 public class Generator { 10 11 public static void main(String[] args) throws IOException { 12 Scanner cin = new Scanner(System.in); 13 String str; 14 while (true) { 15 System.out.print("欢迎使用中小学试卷生成器,请选择你的身份:\n1.小学老师\n2.初中老师\n3.高中老师\n4.退出\n"); 16 str = cin.nextLine(); 17 switch (str) { 18 case "1": 19 PrimaryTeacher.enroll(); 20 return; 21 case "2": 22 JuniorTeacher.enroll(); 23 return; 24 case "3": 25 SeniorTeacher.enroll(); 26 case "4": 27 return; 28 default: 29 System.out.print("输出无效指令请重新选择\n"); 30 } 31 } 32 } 33 }View Code
然后是exampaper包,这里主要实现创建试卷及其所需的txt文件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package exampaper; 2 3 import java.util.Date; 4 5 public interface ExamPaper { 6 String ExamtypeT = ""; 7 int QuestionnumT = 0; 8 9 /* 10 * 创建试卷所需txt 11 */ 12 public static String examPaperCreate(Date time) { 13 return ""; 14 } 15 16 /* 17 * 创建试卷 18 */ 19 public static void examPaperGenerator(int num) {} 20 21 public static boolean check(String str) { 22 return true; 23 } 24 25 }View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package exampaper; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileInputStream; 6 import java.io.FileNotFoundException; 7 import java.io.FileWriter; 8 import java.io.IOException; 9 import java.io.InputStreamReader; 10 import java.time.LocalDateTime; 11 import java.time.format.DateTimeFormatter; 12 import java.util.Date; 13 import question.PrimaryQuestion; 14 15 public class PrimaryExamPaper implements ExamPaper { 16 Date CreatetimeT; 17 String ExamtypeT; 18 int QuestionnumT; 19 20 public static String examPaperCreate(String name) { 21 DateTimeFormatter fmt; 22 fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"); 23 LocalDateTime time; 24 time = LocalDateTime.now(); 25 String address; 26 File file = new File("exampaper\\" + name); // 以某路径实例化一个File对象 27 if (!file.exists()) { // 如果不存在 28 boolean dr = file.mkdirs(); // 创建目录 29 } 30 address = "exampaper\\" + name + "\\" + time.format(fmt) + ".txt"; 31 try { 32 File myObj = new File(address); 33 if (myObj.createNewFile()) { 34 System.out.println("文件已经创建: " + myObj.getName()); 35 } else { 36 37 System.out.println("文件已存在"); 38 } 39 } catch (IOException e) { 40 System.out.println("发生错误"); 41 e.printStackTrace(); 42 } 43 return address; 44 } 45 46 47 public static boolean check(String str) throws IOException { 48 String file; 49 file = "exampaper\\total.txt"; 50 FileInputStream fin; 51 fin = null; 52 try { 53 fin = new FileInputStream(file); 54 } catch (FileNotFoundException e) { 55 e.printStackTrace(); 56 } 57 InputStreamReader reader; 58 reader = new InputStreamReader(fin); 59 BufferedReader buffReader; 60 buffReader = new BufferedReader(reader); 61 String strTmp = ""; 62 while ((strTmp = buffReader.readLine()) != null) { 63 if (str.equals(strTmp)) { 64 return false; 65 } 66 } 67 File file1; 68 file1 = new File("exampaper\\total.txt"); 69 try (FileWriter writer = new FileWriter(file1, true)) { 70 writer.write(str + "\n"); 71 } 72 buffReader.close(); 73 return true; 74 } 75 76 77 public static void examPaperGenerator(int num, String name) { 78 String address; 79 address = examPaperCreate(name); 80 File file = new File(address); 81 // 如果文件不存在,创建文件 82 try { 83 if (!file.exists()) { 84 file.createNewFile(); 85 } 86 FileWriter writer = new FileWriter(file); 87 while (num > 0) { 88 String str; 89 str = PrimaryQuestion.questionGenerator(); 90 if (check(str)) { 91 writer.write("小学题目: " + str + " = \n"); 92 writer.flush(); 93 num = num - 1; 94 95 } 96 } 97 // 向文件中写入内容 98 } catch (IOException e) { 99 e.printStackTrace(); 100 } 101 } 102 103 }View Code
然后是question,主要实现三种不同类型的问题。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package question; 2 3 public interface Question { 4 String TypeT = ""; 5 boolean StatusT = true; 6 7 public static String questionGenerator() { 8 return ""; 9 } 10 11 public static int intRandom(int min, int max) { 12 return 0; 13 } 14 15 public static String addLeftParentheses(int num, String str) { 16 return ""; 17 } 18 }View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package question; 2 3 import java.util.LinkedList; 4 import java.util.Random; 5 6 public class PrimaryQuestion implements Question { 7 String TypeT; 8 boolean StatusT; 9 static String[] Primary = {"+", "-", "×", "÷"}; 10 11 12 public static LinkedList<Integer> Parenthesesite(int leftParentheseNum, int now, int num) { 13 LinkedList<Integer> right; 14 right = new LinkedList<Integer>(); 15 for (int i = 0; i < now; i++) { 16 right.add(0); 17 } 18 int judge; // 判断该处该不该使用右括号1为用0为不用 19 while (leftParentheseNum != 0) { 20 if (num - now == leftParentheseNum) { 21 right.add(1); 22 leftParentheseNum--; 23 } else { 24 judge = intRandom(0, 1); 25 if (judge == 1) { 26 right.add(1); 27 leftParentheseNum--; 28 } else { 29 right.add(0); 30 } 31 } 32 now++; 33 } 34 return right; 35 } 36 37 38 public static int intRandom(int min, int max) { 39 Random r = new Random(); 40 int num; 41 num = r.nextInt(max - min + 1) + min; 42 return num; 43 } 44 45 46 public static String addLeftParentheses(int num, String str) { 47 for (int i = 0; i < num; i++) { 48 str = str + "("; 49 } 50 return str; 51 } 52 53 54 public static String questionGenerator() { 55 int num;// 操作数数量 56 int now; 57 int leftParentheseNum; 58 leftParentheseNum = 0; 59 LinkedList<Integer> right; 60 right = new LinkedList<Integer>(); 61 String question; 62 question = ""; 63 num = intRandom(2, 5); 64 now = 0; 65 while (now != num) { 66 now = now + 1; 67 if (leftParentheseNum == 0) { 68 leftParentheseNum = intRandom(0, num - now); 69 right = Parenthesesite(leftParentheseNum, now, num); 70 question = addLeftParentheses(leftParentheseNum, question); 71 } 72 question = question + " " + Integer.toString(intRandom(1, 100)) + " "; 73 if (right.get(now - 1) == 1) { 74 question = question + ")"; 75 leftParentheseNum--; 76 } 77 if (now != num) { 78 question = question + Primary[intRandom(0, 3)]; 79 } 80 } 81 return question; 82 } 83 }View Code
最后是teacher,主要实现老师登录的操作
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package teacher; 2 3 4 public interface Teacher { 5 /* 6 * 登录界面 7 */ 8 9 public static void enroll() {} 10 11 /* 12 * 使用界面 13 */ 14 public static void userInterface(String str) {} 15 16 /* 17 * 文件中寻找账号信息比对 18 */ 19 public static boolean check(String str) { 20 return true; 21 } 22 23 }View Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package teacher; 2 3 import java.io.BufferedReader; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.io.InputStreamReader; 8 import java.util.Random; 9 import java.util.Scanner; 10 import exampaper.PrimaryExamPaper; 11 12 public class PrimaryTeacher implements Teacher { 13 14 15 public static boolean check(String str) throws IOException { 16 String file; 17 file = "teacher_list\\teacher_list.txt"; 18 FileInputStream fin; 19 fin = null; 20 try { 21 fin = new FileInputStream(file); 22 } catch (FileNotFoundException e) { 23 e.printStackTrace(); 24 } 25 InputStreamReader reader; 26 reader = new InputStreamReader(fin); 27 BufferedReader buffReader; 28 buffReader = new BufferedReader(reader); 29 String strTmp = ""; 30 while ((strTmp = buffReader.readLine()) != null) { 31 if (str.equals(strTmp)) { 32 return true; 33 } 34 } 35 buffReader.close(); 36 return false; 37 } 38 39 public static void enroll() throws IOException { 40 Scanner cin = new Scanner(System.in); 41 System.out.print(" û : "); 42 String id; 43 String passWord; 44 id = cin.next(); 45 System.out.print(" : "); 46 passWord = cin.next(); 47 System.out.println(id); 48 String str; 49 str = "Primary " + id + " " + passWord; 50 if (check(str) == true) { 51 userInterface(id); 52 } else { 53 System.out.println(" Ǹ "); 54 } 55 cin.close(); 56 } 57 58 public static void userInterface(String str) { 59 System.out.print(" ӭ" + str + "ʹ Ծ ϵͳ\n"); 60 System.out.print(" 봴 Ծ Ŀ (0 ʾ ȡһ Ŀ,-1 ˳ ) "); 61 Scanner cin = new Scanner(System.in); 62 int num; 63 num = cin.nextInt(); 64 while (num < 10 || num > 30) { 65 System.out.print(" Ŀ Ϊ \n"); 66 num = cin.nextInt(); 67 } 68 69 if (num == -1) { 70 return; 71 } 72 if (num == 0) { 73 Random r = new Random(); 74 num = r.nextInt(21) + 10; 75 System.out.print(" " + num + " \n"); 76 } 77 PrimaryExamPaper.examPaperGenerator(num, str); 78 cin.close(); 79 } 80 81 }View Code
五、优缺点总结
优点:
-
交互性:通过使用
Scanner
对象,程序与用户进行交互,等待用户输入,这样用户可以根据自己的需要选择操作。 -
模块化:代码使用了不同的类(
JuniorTeacher
、PrimaryTeacher
、SeniorTeacher
)来处理不同类型老师的操作,这提高了代码的可维护性和可扩展性。 - 灵活性:代码使用了可配置的参数,如操作数数量、运算符类型等,这使得生成的题目可以根据需要进行定制。
- 对于括号“()”的操作实现较符合正常逻辑,不会出现两个位置相同的左括号他对应的右括号位置也相同,通过一个链表先随机左括号数量再利用随机寻找右括号位置将其存入链表之中
缺点:
1.用户输入验证:虽然代码在某些地方验证了用户输入的有效性,但还可以改进。例如,应该在用户输入密码时进行密码验证。
2.缺少注释:代码中没有提供足够的注释来解释各个方法的功能和逻辑,这可能会使代码难以理解。
六、个人收获
-
观察了同学的代码风格,包括缩进、变量命名和格式化,以学习更好的的代码编写风格,使代码易于阅读和维护。
- 学习代码改进:通过检查同学的代码中的缺点和问题,可以学习如何改进代码,使其更加稳健、可维护和高效。
标签:java,String,个人,互评,num,HNU,str,import,public From: https://www.cnblogs.com/2256232417sh/p/17718705.html