HNU个人项目互评

发布时间 2023-09-21 00:01:39作者: der~10086

代码:梁欢

评价:韩成玉

一、题目介绍

用户

小学、初中和高中数学老师。

功能

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;
    }
}

功能:该类主要包括用户界面生成,试卷生成,查重,文件读写这几类功能。

三、结果展示

以下为实际效果展示

 可以看到结果正常。