HNU个人项目互评

目录

  1. 简介
  2. 代码分析与功能测试
  3. 总结

一、简介

         此次博客是我对结伴项目队友符挺博个人项目的评价(使用的语言是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”的形式保存,每个账号一个文件夹。每道题目有题号,每题之间空一行;

 

二、代码分析与功能测试

代码分析

主要代码分析:这里将加减乘除运算、加括号、加平方和平方根、加三角函数分为四个函数,在生成试卷的函数里有需要的再使用这些函数加进去,首先就很有效地避免了代码过长(不超过40行),其次根据随机数一起能更自由地生成不同的题目。

    private static void HasOperation(int i) {
        String str = operands[i];
        int Length = str.length();
        if ((str.charAt(0) == 't') || (str.charAt(0) == 's') || (str.charAt(0) == 'c') || (str.charAt(0) == '√') || (str.charAt(Length - 1) == '²')) {
            operands[i] = "(" + operands[i] + ")";
        }
    }

    //加括号方法
    protected static void parentheses() {
        if (operand_num >= 3 && r.nextInt(2) == 0) {
            int length = r.nextInt(operand_num - 1) + 2;
            int left = r.nextInt(operand_num + 1 - length);
            int right = left + length - 1;

            //a b c d e
            //2 ~ 5 -> (0 ~ 3) + 2 -> (4) + 2
            //假设括号长度为3,那么left取值应为0,1,2 (3)
            //长度为4,取值为0,1 (2)
            //即num+1-length
            //假设长度为3,left取值为0,right应在2号位置 = 0+3-1

            //防止两次括号在同一个位置
            int bLength = operands[right].length();
            if (!((operands[left].charAt(0) == '(') && (operands[right].charAt(bLength - 1) == ')'))) {
                StringBuilder tmp = new StringBuilder();
                for (int i = left; i <= right; i++) {
                    tmp.append(operands[i]);
                }
                int TmpLength = tmp.length();
                int leftBracket = 1, HasParentheses = 0;
                for (int i = 1; i < TmpLength - 1; i++) {
                    if (tmp.charAt(i) == '(') {
                        leftBracket++;
                    } else if (tmp.charAt(i) == ')') {
                        leftBracket--;
                    }

                    if (leftBracket == 0) {
                        HasParentheses = 1;
                        break;
                    }
                }
                if (HasParentheses == 1) {
                    operands[left] = "(" + operands[left];
                    operands[right] = operands[right] + ")";
                }
            }
        }
    }

    //添加四则运算
    protected static void Add_Four_Operation(int cur, String[] Problem) {
        for (int i = 0; i < operand_num; i++) {
            if (i != operand_num - 1) {
                //随机添加符号
                operands[i] += signs[r.nextInt(4)];
            }
            Problem[cur] += operands[i];
        }
        Problem[cur] = SubParentheses(Problem[cur]) + "=";
    }

    //初中加根号和平方运算
    protected static void Add_Middle_Operation() {
        //Middle_Operation表示有多少个平方和开方运算
        int index = r.nextInt(operand_num);
        HasOperation(index);
        if (r.nextInt(2) == 0) {
            operands[index] = operands[index] + "²";
        } else {
            operands[index] = "√" + operands[index];
        }
    }

    //高中加三角函数运算
    protected static void Add_High_Operation() {
        //High_operation表示有多少个三角运算
        int index = r.nextInt(operand_num);
        HasOperation(index);
        int cur = r.nextInt(3);
        if (cur == 0) {
            operands[index] = "sin" + operands[index];
        } else if (cur == 1) {
            operands[index] = "cos" + operands[index];
        } else {
            operands[index] = "tan" + operands[index];
        }
    }

    //除去最大的括号
    protected static String SubParentheses(String formula) {
        String tmp = formula;
        int length = tmp.length();
        if ((tmp.charAt(0) == '(') && (tmp.charAt(length - 1) == ')')) {
            //System.out.println("发现题目有大括号: " + formula);
            int left = 1, right = 0, HasParentheses = 0;
            for (int i = 1; i < length - 1; i++) {
                if (tmp.charAt(i) == '(') {
                    left++;
                } else if (tmp.charAt(i) == ')') {
                    right++;
                }

                if (right == left) {
                    HasParentheses = 1;
                    break;
                }
            }
            if (HasParentheses == 0) {
                tmp = formula.substring(1, length - 1);
            }
        }
        return tmp;
    }
View Code

用户操作界面的代码的分析:这里是将判定切换为小学、初中、高中或其他年级,还有生成试卷的功能与操作界面分开,一是简介明了,二是代码不会超过40行。

/**
   * 用户操作界面.
   * @param user 传入操作的用户,指明是哪个用户正在操作.
   */
  public void userActionPage(User user) {
    System.out.print("当前选择为" + type + "出题\n");
    System.out.print("准备生成" + type + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):\n");
    int isLogin = 1;
    String input = sc.next();
    while (true) {
      if (input.equals("-1")) {
        isLogin = 0;
      }
      if (isLogin == 0) {
        System.out.print("账号已经退出登录\n");
        break;
      }
      if (input.matches("\\d+")) {
        if (getNum(Integer.parseInt(input)) != 0) {
          getPaper(getNum(Integer.parseInt(input)), user.getType(), user);
          System.out.print("当前选择为" + type + "出题\n");
          System.out.print("准备生成" + type + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):\n");
        }
        input = sc.next();
        continue;
      }
      if (input.contains("切换为")) {
        String change = changeType(input);
        if (Objects.equals(change, "error")) {
          System.out.print("请输入小学、初中和高中三个选项中的一个\n");
        } else {
          type = change;
          System.out.print("准备生成" + type + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):\n");
        }
      } else {
        System.out.print("输入有误,请重新输入:\n");
      }
      input = sc.next();
    }
  }

  /**
   * 获取试卷题目存入problem[]中.
   * @param total 传入想要出题的数量.
   * @param type 传入想要出题的类型.
   * @param user 传入想要出题的账户,用于存储和查重.
   */
  public static void getPaper(int total, String type, User user) {
    //定义生成题目total道
    problem = new String[total];
    switch (type) {
      case "小学" -> {
        PrimaryPaper primaryPaper = new PrimaryPaper();
        primaryPaper.creatPaper(total, problem, user);
      }
      case "初中" -> {
        MiddlePaper middlePaper = new MiddlePaper();
        middlePaper.creatPaper(total, problem, user);
      }
      case "高中" -> {
        HighPaper highPaper = new HighPaper();
        highPaper.creatPaper(total, problem, user);
      }
      default -> {
      }
    }
    PaperFiles.writeFile(problem, total, user);
  }

  /**
   * 修改老师出题的类型.
   * @param input 传入输入的字符串.
   * @return 返回想要修改的出题的类型,如果返回error代表错误.
   */
  public static String changeType(String input) {
    if (input.equals("切换为小学")) {
      return "小学";
    }
    if (input.equals("切换为初中")) {
      return "初中";
    }
    if (input.equals("切换为高中")) {
      return "高中";
    }
    return "error";
  }

  /**
   * 获取题目的数量.
   * @param n 传入写入的题目数量.
   * @return 返回获取的题目的数量.
   */
  public static int getNum(int n) {
    if (n < 10 || n > 30) {
      System.out.print("范围有误,请重新输入:\n");
      return 0;
    } else {
      return n;
    }
  }
}
View Code

主函数

 public static void main(String[] args) throws IOException {

    File file = new File("../", "PaperCreation");
    if (!file.exists()) {
      file.mkdir();
    }

    while (true) {
      System.out.print("------中小学生题库生成系统------\n");
      System.out.print("请输入账号和密码:");
      Login login = new Login();
      String type = login.userLoginView();
      if (Objects.equals(type, "error")) {
        System.out.print("请输入正确的用户名、密码\n");
      } else if (type.equals("退出")) {
        break;
      }
    }
  }
View Code

 

功能测试

登录界面:

 密码或账户名错误会有重新输入的提示:

 登录成功则进入下一界面并能成功执行全部功能:

 输入的题数不在范围内也会给出提示并重新输入:

生成的账户和题目如下所示:

 

三、总结

代码的优点:1.各部分代码写得简洁利落,没有冗长的部分,每一个方法函数都没超过40行;

                      2.代码规范做得好,基本上没有代码规范错误;

                      3.功能实现很好,可以生成老师账户和随机生成题目,不会显得题目十分简单;

代码的缺点:代码可能某些变量没有用到,或者变量定义有重复的都会有些警告,这部分可以删去。

通过这次的个人项目以及互评,我也能深刻体会到做这个项目给我带来的好处以及不足,还有许多能提升的地方,更需要注意的细节等。

posted @ 2023-09-20 21:28  软件2102庞大军  阅读(351)  评论(0)    收藏  举报