结对编程——中小学数学卷子自动生成程序队友项目互评

结构:
队友代码分了三个包,六个.java文件

1.User.java:定义了User类,存储User的属性和一些简单的调用方法。

点击查看代码
package com.users;

public class User {
    private String name;
    private String password;
    private int grade;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getGrade() {
        return grade;
    }
    public void setGrade(int grade) {
        this.grade = grade;
    }
}

2. UserInit.java:初始化User,读取user.txt中user的信息保存到List容器中,还定义了用户登录的方法login(List users)。
点击查看代码
package com.users;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class UserInit {
    public static String dir = "D:\\Auni\\大三上\\软件工程导论\\个人项目\\202026010516-陈雪萍-第一周大项目\\";
    public static List<User> Init() {
        List<User> users = new ArrayList<>();
        File infile = new File(dir + "user.txt");
        try {
            BufferedReader bu = new BufferedReader(new FileReader(infile));//读入文件
            String temp;
            while ((temp = bu.readLine()) != null) {
                String[] stringSplit = temp.split("\\s+");
                User us = new User();
                us.setName(stringSplit[0]);
                us.setPassword(stringSplit[1]);
                if (stringSplit[2].equals("小学")) {
                    us.setGrade(1);
                }
                if (stringSplit[2].equals("初中")) {
                    us.setGrade(2);
                }
                if (stringSplit[2].equals("高中")) {
                    us.setGrade(3);
                }
                users.add(us);
            }
            bu.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return users;//返回全部用户
    }

    public static User login(List<User> users) {
        System.out.println("请输入用户名和密码:");
        Scanner sc = new Scanner(System.in);
        boolean flag = false;
        User us = new User();
        while (!flag) {
            String[] s = sc.nextLine().split("\\s+");
            if (s.length < 2) {
                System.out.println("请输入正确的用户名、密码:");
                continue;
            }
            String name = s[0];
            String password = s[1];
            for (User user : users) {
                if (user.getName().equals(name) && user.getPassword().equals(password)) {
                    flag = true;
                    int grade = user.getGrade();
                    us.setGrade(user.getGrade());
                    us.setName(user.getName());
                    us.setPassword(user.getPassword());
                    System.out.print("当前选择为");
                    if (grade == 1) {
                        System.out.print("小学");
                    }
                    if (grade == 2) {
                        System.out.print("初中");
                    }
                    if (grade == 3) {
                        System.out.print("高中");
                    }
                    System.out.println("出题");
                    break;
                }
            }
            if (!flag) {
                System.out.println("请输入正确的用户名、密码:");
            }
        }
        return us;
    }
}
3. GetVal.java:写了数学题目的生成逻辑,数学卷子的生成逻辑。
点击查看代码
package com.math;

import java.io.*;
import java.util.HashSet;
import java.util.Random;

public class GetVal {
    public static String dir = "D:\\Auni\\大三上\\软件工程导论\\个人项目\\202026010516-陈雪萍-第一周大项目\\";
    public String getval(int state) {
        String[] operands = new String[]{"+", "-", "*", "/", "^2", "√", "sin", "cos", "tan"};
        Random dome = new Random();
        StringBuilder val = new StringBuilder(new String());
        if (state == 1) {
            while (true) {
                val = new StringBuilder();
                int length = 0;
                int numberOfNodes = dome.nextInt(3);
                int left = 0;
                int temp = 0;
                while (true) {
                    if (dome.nextInt(2) == 0 && numberOfNodes > 0) {
                        val.append("(");
                        numberOfNodes--;
                        left++;
                        temp = 0;
                    }
                    int num = dome.nextInt(100) + 1;
                    val.append(num);
                    temp++;
                    if (dome.nextInt(2) == 0 && left > 0 && temp >= 2) {
                        val.append(")");
                        left--;
                    }
                    if (length >= 2 && numberOfNodes <= 0 && left <= 0) {
                        break;
                    }
                    val.append(operands[dome.nextInt(4)]);
                    length++;
                }
                if (length < 5 && temp < 3) {
                    break;
                }
            }
        }
        if (state == 2) {
            while (true) {
                val = new StringBuilder();
                int length = 0;
                int oprand = dome.nextInt(2) + 1;
                int numberOfNodes = dome.nextInt(2);
                int left = 0;
                int temp = 0;
                while (true) {
                    if (dome.nextInt(2) == 0 && numberOfNodes > 0) {
                        val.append("(");
                        numberOfNodes--;
                        left++;
                        temp = 0;
                    }
                    temp++;
                    int num = dome.nextInt(100) + 1;
                    if (dome.nextInt(2) == 0) {
                        if (dome.nextInt(2) == 0) {
                            val.append(num).append(operands[4]);
                        } else {
                            val.append(operands[5]).append(num);
                        }
                        oprand--;
                    } else {
                        val.append(num);
                    }
                    if (dome.nextInt(2) == 0 && left > 0 && temp >= 2) {
                        val.append(")");
                        left--;
                    }
                    if (length >= 2 && oprand <= 0 && numberOfNodes <= 0 && left <= 0) {
                        break;
                    }
                    val.append(operands[dome.nextInt(4)]);
                    length++;
                }
                if (length < 5 && temp < 5) {
                    break;
                }
            }
        }
        if (state == 3) {
            while (true) {
                val = new StringBuilder();
                int length = 0;
                int minCount = 1;
                int trigFunc = dome.nextInt(3) + 1;
                int numberOfNodes = dome.nextInt(3);
                int left = 0;
                int temp = 0;
                while (true) {
                    if (dome.nextInt(2) == 0 && numberOfNodes > 0) {
                        val.append("(");
                        numberOfNodes--;
                        left++;
                        temp = 0;
                    }
                    temp++;
                    int num = dome.nextInt(100) + 1;
                    if (dome.nextInt(3) == 0) {
                        if (dome.nextInt(2) == 0) {
                            val.append(num).append(operands[4]);
                        } else {
                            val.append(operands[5]).append(num);
                        }
                        minCount--;
                    } else {
                        if (dome.nextInt(2) == 0) {
                            int need = dome.nextInt(3) + 6;
                            val.append(operands[need]).append(num);
                            trigFunc--;
                        } else {
                            val.append(num);
                        }
                    }
                    if (dome.nextInt(2) == 0 && left > 0 && temp >= 2) {
                        val.append(")");
                        left--;
                    }
                    if (length >= 2 && minCount <= 0 && trigFunc <= 0 && numberOfNodes <= 0 && left <= 0) {
                        break;
                    }
                    val.append(operands[dome.nextInt(4)]);
                    length++;
                }
                if (length < 5 && temp < 5) {
                    break;
                }
            }
        }
        val.append("=");
        return val.toString();
    }

    public HashSet<String> getAll(String name) {
        String dpath = dir + name;
        File file = new File(dpath);
        if (!file.exists()) {
            file.mkdir();
        }
        File[] files = file.listFiles();
        HashSet<String> pastVal = new HashSet<>();
        assert files != null;
        for (File fs : files) {
            if (!fs.isDirectory()) {
                try {
                    BufferedReader br = new BufferedReader(new FileReader(fs));
                    String line;
                    while ((line = br.readLine()) != null) {
                        pastVal.add(line);
                    }
                    br.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return pastVal;
    }
}
4. OutFile.java:生成数学卷子。
点击查看代码
package com.math;

import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;

public class OutFile {
    public static String dir = "D:\\Auni\\大三上\\软件工程导论\\个人项目\\202026010516-陈雪萍-第一周大项目\\";
    public static void out(String name, int state, int num) {
        GetVal p1=new GetVal();
        HashSet<String> past = p1.getAll(name);
        String dirPath = dir + name;

        final SimpleDateFormat SDF = new SimpleDateFormat();
        SDF.applyPattern("yyyy-MM-dd-HH-mm-ss");
        String path = dirPath + "\\" + SDF.format(new Date()) + ".txt";

        try {
            FileWriter add = new FileWriter(path, true);
            for (int i = 0; i < num; i++) {
                String newVal = p1.getval(state);
                if (!past.contains(newVal)) {
                    newVal = (i + 1) + "." + newVal;
                    add.write(newVal+ "\n" + "\n");
                }
            }
            System.out.println("卷子生成完毕");
            add.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5. Judge.java:主要是用户登录后的一些处理,比如说如何判断生成题目类型,如何切换题目。
点击查看代码
package com.system;

import com.math.OutFile;
import com.users.User;
import com.users.UserInit;
import java.util.List;
import java.util.Scanner;

public class Judge {
    public static final String primary     = "小学";
    public static final String junior    = "初中";
    public static final String senior    = "高中";
    static int input(int state) {
        System.out.print("准备生成");//对应的年级输出相应的提示语
        if (state == 1) {
            System.out.print(primary);
        }
        if (state == 2) {
            System.out.print(junior);
        }
        if (state == 3) {
            System.out.print(senior);
        }
        System.out.println("数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):");
        int temp = 0;
        Scanner in = new Scanner(System.in);
        String input = in.nextLine();
        while (true) {
            if (input.contains("切换为")) {
                while (true) {
                    if (input.equals("切换为小学")) {
                        temp = 1;
                        break;
                    }
                    if (input.equals("切换为初中")) {
                        temp = 2;
                        break;
                    }
                    if (input.equals("切换为高中")) {
                        temp = 3;
                        break;
                    }
                    System.out.println("请输入小学、初中和高中三个选项中的一个");//不满足条件继续重新输入
                    input = in.nextLine();
                }
            }
            if (input.equals("-1")) {
                temp = -1;
            }
            if (input.matches("\\d+")) {
                int num = Integer.parseInt(input);
                if (num >= 10 && num < 30) {
                    temp = num;
                } else {
                    System.out.println("输入范围错误,请重新输入");
                    input = in.nextLine();
                    continue;
                }
            }
            if(temp == 0) {
                System.out.println("输入错误,请重新输入");
                input = in.nextLine();
                continue;
            }
            break;
        }
        return temp;
    }

    public void change() {
        List<User> users = UserInit.Init();
        User us = UserInit.login(users);
        int newState = us.getGrade();
        while (true) {
            int in = input(newState);
            switch (in) {
                case -1:
                    us = UserInit.login(users);
                    newState = us.getGrade();
                    break;
                case 1:
                    newState = 1;
                    break;
                case 2:
                    newState = 2;
                    break;
                case 3:
                    newState = 3;
                    break;
                default:
                    OutFile.out(us.getName(), newState, in);
            }
        }
    }
}

6. Main.java:是主函数,运行这个函数即可。
点击查看代码
package com.system;

public class Main {
    public static void main(String[] args) {
        Judge j2 = new Judge();
        j2.change();
    }
}

优点:

  1. 结构清晰,模块化
    基于面向对象的思想,用户类、出题类、系统类,Java类分的很清楚,将用户登录、切换、生成试卷、输出试题卷等操作抽象成类,完成封装,封装性能良好。
  2. 异常处理机制
    在使用文件流IO时使用try catch捕捉异常。IO输入容易产生错误,因为可能会有文件路径出错,文件找不到等运行时错误,在编译阶段找不出这些问题。代码中多次用到异常处理机制,比如说OutFile中,由于要输出文件到指定的路径,而我拿了队友代码后修改成自己的路径时出错了,系统给了我出错的提示但并没有终止程序。队友的异常处理使得代码更加健壮。
  3. Main函数
    队友最后调用Main主函数即可跑动程序,一切都被封装起来。
  4. 扩展性强
    队友的代码,User信息存储在user.txt文件中,通过读取这个文件的内容从而构建user的List,如果有新的用户加入,就可以修改user.txt的内容即可,而不用修改代码。我觉得队友的做法和连接数据库有点相似,大大扩展了代码的使用领域。
点击查看代码
    public static List<User> Init() {
        List<User> users = new ArrayList<>();
        File infile = new File(dir + "user.txt");
        try {
            BufferedReader bu = new BufferedReader(new FileReader(infile));//读入文件
            String temp;
            while ((temp = bu.readLine()) != null) {
                String[] stringSplit = temp.split("\\s+");
                User us = new User();
                us.setName(stringSplit[0]);
                us.setPassword(stringSplit[1]);
                if (stringSplit[2].equals("小学")) {
                    us.setGrade(1);
                }
                if (stringSplit[2].equals("初中")) {
                    us.setGrade(2);
                }
                if (stringSplit[2].equals("高中")) {
                    us.setGrade(3);
                }
                users.add(us);
            }
            bu.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return users;//返回全部用户
    }

缺点:

  1. 部分代码不规范
    静态常量没有大写,比如
    public static final String primary = "小学";
    部分命名没有遵守驼峰规则,比如
    public String getval(int state)
    此处getval应该写成getVal
  2. 没有查重
    题目要求一个老师不能出重复的题目,队友代码没有写出查重的功能。
    建议队友加上题目查重的功能。
  3. 注释较少,部分代码理解有困难
    队友代码大部分是非常简洁的,就是数学题目生成逻辑那块儿不怎么看得懂,有一些变量可以写上注释,可以便于读者理解。
  4. 通配符
    代码中有通配符,不符合Google代码规范
    import java.io.*;
posted @ 2022-09-13 16:11  绝不摆烂耶耶耶  阅读(236)  评论(0编辑  收藏  举报