结对编程队友代码分析
使用java语言编写。
优点:将用户单独作为一个User类,方便用户数据处理和管理。在主类Paper类中,包含了main函数和实现各种功能的方法,main函数非常简单,容易理解,作业要求的各种功能分别由不同的功能方法实现,容易使用,同时代码没有多少难以理解的地方,逻辑清晰,代码注释也标记到位,减少理解成本。
缺点:
第一,将所有功能方法和mian写到一个类中,虽然这样写起来方便,但会导致写出来的代码难以维护,而且几乎没有拓展性,以后想增加某个功能,比如增加大学的题目生成,那么将会有很多地方需要修改,工程量很大,没有体现出java面向对象编程的思想。
第二,将所有方法写到一个类中,会造成这一个类过大,代码量很长,不便于阅读和整理。
第三,有编程规范错误,且在方法前没有写明javadoc,不便于读者对代码的阅读
代码如下
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Scanner; public class Paper { public static String dir="C:\\Users\\QWTG\\Desktop\\中小学数学卷子自动生成\\";//主文件夹位置 public static void main(String[] args) { //主函数 List<User> users=userInitialize(); User iuser=login(users);//记录当前用户 int state=iuser.getGrade();//记录当前年级状态 while(true){ int input=getInput(state); switch (input){ case -1:iuser=login(users);//输入-1重新登录 state=iuser.getGrade(); break; case 1:state=1;//改变年级状态 break; case 2:state=2;//改变年级状态 break; case 3:state=3;//改变年级状态 break; default:getPaper(iuser.getName(),state,input);//获得试卷 } } } static List<User> userInitialize(){ //用户初始化,读入文件中的用户信息并返回 List<User> users=new ArrayList<User>(); File infile = new File(dir+"user.txt");//用户信息文件 try { BufferedReader bf = new BufferedReader(new FileReader(infile));//读入文件 String temp; while((temp=bf.readLine())!=null) { String[] stringSplit=temp.split("\\s+");//按空格切分 User iuser=new User();// iuser.setName(stringSplit[0]);//设置姓名 iuser.setPassword(stringSplit[1]);//设置密码 if(stringSplit[2].equals("小学")){//设置年级 iuser.setGrade(1); } if(stringSplit[2].equals("初中")){ iuser.setGrade(2); } if(stringSplit[2].equals("高中")){ iuser.setGrade(3); } users.add(iuser);//添加至用户链表 } bf.close(); }catch(Exception e){ e.printStackTrace(); return null; } return users;//返回全部用户 } static User login(List<User> users){ //登录用户 System.out.println("请输入用户名和密码:"); Scanner in=new Scanner(System.in); boolean flag=false;//标记位用来标记是否登录 User iuser=new User();//表示登录用户 while(!flag) { String str[] = in.nextLine().split("\\s+"); if(str.length<2){//输入少于两个字段 System.out.println("请输入正确的用户名、密码:"); continue; } String name = str[0];//记录姓名 String password = str[1];//记录密码 for(User user:users){ if(user.getName().equals(name)&&user.getPassword().equals(password)){//存在用户满足该用户名和密码 flag=true; int grade=user.getGrade(); iuser.setName(user.getName());//设置用户名 iuser.setPassword(user.getPassword());//设置密码 iuser.setGrade(user.getGrade());//设置年级 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("请输入正确的用户名、密码:");//如果没有满足该用户的账户,登录失败,重新输入 } } in.close(); return iuser;//返回登录的账户信息 } static int getInput(int state){ //接收输入,根据相应的输入完成登出、更换状态、生成试卷 System.out.print("准备生成");//对应的年级输出相应的提示语 if (state==1){ System.out.print("小学"); } if (state==2){ System.out.print("初中"); } if (state==3){ System.out.print("高中"); } System.out.println("数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):"); int get=0; Scanner in=new Scanner(System.in); String input=in.nextLine();//接收输入 while (true){ if(input.contains("切换为")){//如果满足字符串“切换为”则进行判断 while (true){ if(input.equals("切换为小学")){//满足条件跳出循环 get=1; break; } if(input.equals("切换为初中")){ get=2; break; } if(input.equals("切换为高中")){ get=3; break; } System.out.println("请输入小学、初中和高中三个选项中的一个");//不满足条件继续重新输入 input=in.nextLine(); } } if(input.equals("-1")){//输入为1登出原来的用户 get=-1; } if (input.matches("\\d+")){//满足输入的是数字 int num=Integer.valueOf(input); if (num>=10&&num<30){//在10到30之间满足条件 get=num; }else{ System.out.println("输入范围错误,请重新输入");//不满足条件重新输入 input=in.nextLine(); continue; } } if (get!=0){//输入有效则跳出循环返回结果 break; }else{ System.out.println("输入错误,请重新输入"); } } in.close(); return get; } static String getProblem(int state){ String[] symbol=new String[]{"+","-","*","/","^2","√","sin","cos","tan"};//设置字符串数组保存符号 Random r = new Random();//产生随机数种子 String problem=new String();//创建字符串来保存结果 if(state==1){//当状态为小学时 while(true){ problem=""; int length=0;//表示式子的长度 int bracket=r.nextInt(3);//表示括号个数,随机化0.1.2 int left=0;//表示左括号多余的个数 int gap=0;//表示左右括号之间的跨度 while(true){ if(r.nextInt(2)==0&&bracket>0){//1/2的几率在数前加入左括号 problem+="(";//式子加入左括号 bracket--;//括号次数 left++;//差值加一 gap=0;//初始化跨度 } int num=r.nextInt(100)+1;//加入0-100随机化数 problem+=String.valueOf(num);//把数加入式子 gap++;//跨度加一 if(r.nextInt(2)==0&&left>0&&gap>=2){//1/2的几率且满足差值大于0且跨度大于2时加入右括号 //if(left>0&&gap>=2){ problem+=")"; left--; } if(length>=2&&bracket<=0&&left<=0){//长度大于2且括号个数为0且差值为0生成结束 break; } problem+=symbol[r.nextInt(4)];//式子中再加入符号 length++;//长度加一 } if(length<5&&gap<3){//过滤掉长度大于5且差值过大的式子 break; } } } if(state==2){ while (true){ problem=""; int length=0; int sym=r.nextInt(2)+1;//初始化平方根号个数大于1的随机数 int bracket=r.nextInt(2); int left=0; int gap=0; while (true){ if(r.nextInt(2)==0&&bracket>0){ problem+="("; bracket--; left++; gap=0; } gap++; int num=r.nextInt(100)+1; if(r.nextInt(2)==0){//将第一步加入数字的步骤改为1/2加入根号平方 if(r.nextInt(2)==0){//1/2的概率加入平方 problem+=(String.valueOf(num)+symbol[4]); }else{//1/2的概率加入根号 problem+=(symbol[5]+String.valueOf(num)); } sym--; }else{//1/2的概率还是加入数字 problem+=String.valueOf(num); } if(r.nextInt(2)==0&&left>0&&gap>=2){ problem+=")"; left--; } if(length>=2&&sym<=0&&bracket<=0&&left<=0){ break; } problem+=symbol[r.nextInt(4)]; length++; } if(length<5&&gap<5){ break; } } } if(state==3){ while(true){ problem=""; int length=0; int sym=1; int sym2=r.nextInt(3)+1;//初始化三角函数个数大于1的整数 int bracket=r.nextInt(3); int left=0; int gap=0; while (true){ if(r.nextInt(2)==0&&bracket>0){ problem+="("; bracket--; left++; gap=0; } gap++; int num=r.nextInt(100)+1; if(r.nextInt(3)==0){//1/3的概率加入平方根号 if(r.nextInt(2)==0){ problem+=(String.valueOf(num)+symbol[4]); }else{ problem+=(symbol[5]+String.valueOf(num)); } sym--; }else {//1/2的概率加入三角函数 if(r.nextInt(2)==0){ int symloc=r.nextInt(3)+6; problem+=(symbol[symloc]+String.valueOf(num)); sym2--; }else {//1/2的概率加入普通符号 problem+=String.valueOf(num); } } if(r.nextInt(2)==0&&left>0&&gap>=2){ problem+=")"; left--; } if(length>=2&&sym<=0&&sym2<=0&&bracket<=0&&left<=0){ break; } problem+=symbol[r.nextInt(4)]; length++; } if(length<5&&gap<5){ break; } } } problem+="="; return problem; } static HashSet<String> getPast(String name){ //获得该用户文件下过去的题目并返回 String path = dir+name; //要遍历的路径 File file = new File(path); //获取其file对象 if(!file.exists()){//如果没有该文件夹进行创建 file.mkdir(); } File[] fs = file.listFiles(); //遍历path下的文件和目录,放在File数组中 HashSet<String> pastProblem= new HashSet<String>(); for(File f:fs) { //遍历File[]数组 if (!f.isDirectory()) //若非目录(即文件),则读入 { try { BufferedReader br = new BufferedReader(new FileReader(f)); String line; while ((line = br.readLine()) != null) { // 一次读入一行数据并加入到结果的hashset中 pastProblem.add(line); } br.close(); } catch (Exception e) { e.printStackTrace(); } } } return pastProblem; } static void getPaper(String name,int state,int num){ //根据用户名,用户年级,在对应的文件夹下生成对应数量的题目 HashSet<String> past=getPast(name);//获得之前生成的题目的hashset String dirPath = dir+name;// 文件夹路径 Calendar cal = Calendar.getInstance(); int year = cal.get(Calendar.YEAR);//获取年份 int month=cal.get(Calendar.MONTH);//获取月份 int day=cal.get(Calendar.DATE);//获取日 int hour=cal.get(Calendar.HOUR);//小时 int minute=cal.get(Calendar.MINUTE);//分 int second=cal.get(Calendar.SECOND);//秒 String path=dirPath+"\\"+String.valueOf(year)+"-"+String.valueOf(month)+"-"+String.valueOf(day)+"-"+String.valueOf(hour)+"-"+String.valueOf(minute)+"-"+String.valueOf(second)+".txt";//设置文件名 try { FileWriter fw = new FileWriter(path,true);//设置追加属性,不断对文件进行追加 for(int i=0;i<num;i++){//生成对应数量题目 String problem=getProblem(state);//生成相应状态的题目 if(!past.contains(problem)){//如果已有的题目中不包含该题目 problem=String.valueOf(i+1)+"."+problem;//加上序号 fw.write(problem+"\n"+"\n");//追加至问价尾 } } System.out.println("卷子生成完毕"); fw.close(); } catch (IOException e) { e.printStackTrace(); } } }
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Paper {
public static String dir="C:\\Users\\QWTG\\Desktop\\中小学数学卷子自动生成\\";//主文件夹位置
public static void main(String[] args) { //主函数
List<User> users=userInitialize();
User iuser=login(users);//记录当前用户
int state=iuser.getGrade();//记录当前年级状态
while(true){
int input=getInput(state);
switch (input){
case -1:iuser=login(users);//输入-1重新登录
state=iuser.getGrade();
break;
case 1:state=1;//改变年级状态
break;
case 2:state=2;//改变年级状态
break;
case 3:state=3;//改变年级状态
break;
default:getPaper(iuser.getName(),state,input);//获得试卷
}
}
}
static List<User> userInitialize(){ //用户初始化,读入文件中的用户信息并返回
List<User> users=new ArrayList<User>();
File infile = new File(dir+"user.txt");//用户信息文件
try {
BufferedReader bf = new BufferedReader(new FileReader(infile));//读入文件
String temp;
while((temp=bf.readLine())!=null) {
String[] stringSplit=temp.split("\\s+");//按空格切分
User iuser=new User();//
iuser.setName(stringSplit[0]);//设置姓名
iuser.setPassword(stringSplit[1]);//设置密码
if(stringSplit[2].equals("小学")){//设置年级
iuser.setGrade(1);
}
if(stringSplit[2].equals("初中")){
iuser.setGrade(2);
}
if(stringSplit[2].equals("高中")){
iuser.setGrade(3);
}
users.add(iuser);//添加至用户链表
}
bf.close();
}catch(Exception e){
e.printStackTrace();
return null;
}
return users;//返回全部用户
}
static User login(List<User> users){ //登录用户
System.out.println("请输入用户名和密码:");
Scanner in=new Scanner(System.in);
boolean flag=false;//标记位用来标记是否登录
User iuser=new User();//表示登录用户
while(!flag) {
String str[] = in.nextLine().split("\\s+");
if(str.length<2){//输入少于两个字段
System.out.println("请输入正确的用户名、密码:");
continue;
}
String name = str[0];//记录姓名
String password = str[1];//记录密码
for(User user:users){
if(user.getName().equals(name)&&user.getPassword().equals(password)){//存在用户满足该用户名和密码
flag=true;
int grade=user.getGrade();
iuser.setName(user.getName());//设置用户名
iuser.setPassword(user.getPassword());//设置密码
iuser.setGrade(user.getGrade());//设置年级
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("请输入正确的用户名、密码:");//如果没有满足该用户的账户,登录失败,重新输入
}
}
in.close();
return iuser;//返回登录的账户信息
}
static int getInput(int state){ //接收输入,根据相应的输入完成登出、更换状态、生成试卷
System.out.print("准备生成");//对应的年级输出相应的提示语
if (state==1){
System.out.print("小学");
}
if (state==2){
System.out.print("初中");
}
if (state==3){
System.out.print("高中");
}
System.out.println("数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):");
int get=0;
Scanner in=new Scanner(System.in);
String input=in.nextLine();//接收输入
while (true){
if(input.contains("切换为")){//如果满足字符串“切换为”则进行判断
while (true){
if(input.equals("切换为小学")){//满足条件跳出循环
get=1;
break;
}
if(input.equals("切换为初中")){
get=2;
break;
}
if(input.equals("切换为高中")){
get=3;
break;
}
System.out.println("请输入小学、初中和高中三个选项中的一个");//不满足条件继续重新输入
input=in.nextLine();
}
}
if(input.equals("-1")){//输入为1登出原来的用户
get=-1;
}
if (input.matches("\\d+")){//满足输入的是数字
int num=Integer.valueOf(input);
if (num>=10&&num<30){//在10到30之间满足条件
get=num;
}else{
System.out.println("输入范围错误,请重新输入");//不满足条件重新输入
input=in.nextLine();
continue;
}
}
if (get!=0){//输入有效则跳出循环返回结果
break;
}else{
System.out.println("输入错误,请重新输入");
}
}
in.close();
return get;
}
static String getProblem(int state){
String[] symbol=new String[]{"+","-","*","/","^2","√","sin","cos","tan"};//设置字符串数组保存符号
Random r = new Random();//产生随机数种子
String problem=new String();//创建字符串来保存结果
if(state==1){//当状态为小学时
while(true){
problem="";
int length=0;//表示式子的长度
int bracket=r.nextInt(3);//表示括号个数,随机化0.1.2
int left=0;//表示左括号多余的个数
int gap=0;//表示左右括号之间的跨度
while(true){
if(r.nextInt(2)==0&&bracket>0){//1/2的几率在数前加入左括号
problem+="(";//式子加入左括号
bracket--;//括号次数
left++;//差值加一
gap=0;//初始化跨度
}
int num=r.nextInt(100)+1;//加入0-100随机化数
problem+=String.valueOf(num);//把数加入式子
gap++;//跨度加一
if(r.nextInt(2)==0&&left>0&&gap>=2){//1/2的几率且满足差值大于0且跨度大于2时加入右括号
//if(left>0&&gap>=2){
problem+=")";
left--;
}
if(length>=2&&bracket<=0&&left<=0){//长度大于2且括号个数为0且差值为0生成结束
break;
}
problem+=symbol[r.nextInt(4)];//式子中再加入符号
length++;//长度加一
}
if(length<5&&gap<3){//过滤掉长度大于5且差值过大的式子
break;
}
}
}
if(state==2){
while (true){
problem="";
int length=0;
int sym=r.nextInt(2)+1;//初始化平方根号个数大于1的随机数
int bracket=r.nextInt(2);
int left=0;
int gap=0;
while (true){
if(r.nextInt(2)==0&&bracket>0){
problem+="(";
bracket--;
left++;
gap=0;
}
gap++;
int num=r.nextInt(100)+1;
if(r.nextInt(2)==0){//将第一步加入数字的步骤改为1/2加入根号平方
if(r.nextInt(2)==0){//1/2的概率加入平方
problem+=(String.valueOf(num)+symbol[4]);
}else{//1/2的概率加入根号
problem+=(symbol[5]+String.valueOf(num));
}
sym--;
}else{//1/2的概率还是加入数字
problem+=String.valueOf(num);
}
if(r.nextInt(2)==0&&left>0&&gap>=2){
problem+=")";
left--;
}
if(length>=2&&sym<=0&&bracket<=0&&left<=0){
break;
}
problem+=symbol[r.nextInt(4)];
length++;
}
if(length<5&&gap<5){
break;
}
}
}
if(state==3){
while(true){
problem="";
int length=0;
int sym=1;
int sym2=r.nextInt(3)+1;//初始化三角函数个数大于1的整数
int bracket=r.nextInt(3);
int left=0;
int gap=0;
while (true){
if(r.nextInt(2)==0&&bracket>0){
problem+="(";
bracket--;
left++;
gap=0;
}
gap++;
int num=r.nextInt(100)+1;
if(r.nextInt(3)==0){//1/3的概率加入平方根号
if(r.nextInt(2)==0){
problem+=(String.valueOf(num)+symbol[4]);
}else{
problem+=(symbol[5]+String.valueOf(num));
}
sym--;
}else {//1/2的概率加入三角函数
if(r.nextInt(2)==0){
int symloc=r.nextInt(3)+6;
problem+=(symbol[symloc]+String.valueOf(num));
sym2--;
}else {//1/2的概率加入普通符号
problem+=String.valueOf(num);
}
}
if(r.nextInt(2)==0&&left>0&&gap>=2){
problem+=")";
left--;
}
if(length>=2&&sym<=0&&sym2<=0&&bracket<=0&&left<=0){
break;
}
problem+=symbol[r.nextInt(4)];
length++;
}
if(length<5&&gap<5){
break;
}
}
}
problem+="=";
return problem;
}
static HashSet<String> getPast(String name){ //获得该用户文件下过去的题目并返回
String path = dir+name; //要遍历的路径
File file = new File(path); //获取其file对象
if(!file.exists()){//如果没有该文件夹进行创建
file.mkdir();
}
File[] fs = file.listFiles(); //遍历path下的文件和目录,放在File数组中
HashSet<String> pastProblem= new HashSet<String>();
for(File f:fs) { //遍历File[]数组
if (!f.isDirectory()) //若非目录(即文件),则读入
{
try {
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null) {
// 一次读入一行数据并加入到结果的hashset中
pastProblem.add(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return pastProblem;
}
static void getPaper(String name,int state,int num){ //根据用户名,用户年级,在对应的文件夹下生成对应数量的题目
HashSet<String> past=getPast(name);//获得之前生成的题目的hashset
String dirPath = dir+name;// 文件夹路径
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);//获取年份
int month=cal.get(Calendar.MONTH);//获取月份
int day=cal.get(Calendar.DATE);//获取日
int hour=cal.get(Calendar.HOUR);//小时
int minute=cal.get(Calendar.MINUTE);//分
int second=cal.get(Calendar.SECOND);//秒
String path=dirPath+"\\"+String.valueOf(year)+"-"+String.valueOf(month)+"-"+String.valueOf(day)+"-"+String.valueOf(hour)+"-"+String.valueOf(minute)+"-"+String.valueOf(second)+".txt";//设置文件名
try {
FileWriter fw = new FileWriter(path,true);//设置追加属性,不断对文件进行追加
for(int i=0;i<num;i++){//生成对应数量题目
String problem=getProblem(state);//生成相应状态的题目
if(!past.contains(problem)){//如果已有的题目中不包含该题目
problem=String.valueOf(i+1)+"."+problem;//加上序号
fw.write(problem+"\n"+"\n");//追加至问价尾
}
}
System.out.println("卷子生成完毕");
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
浙公网安备 33010602011771号