一个简单答题系统的设计与实现(四)

这篇描述生成试卷和练习模式、错题本的功能的思路与实现。

  • 生成试卷

    在平常生活中,考试和平常练习是不同的两种状态,在考试时,试卷有分配好的题型和题数,在本系统中,将其定义为常量:

Constant系统常量类

public class Constant{
	public static final int CHOOSE_NUMBER=50;//选择题题数
	public static final int BLANK_NUMBER=50;//填空题题数
	public static final int JUDGE_NUMBER=50;//判断题题数
	public static final int JD_NUMBER=5;//简答题题数
}

生成试卷时,题目的选取都是随机的,封装一个能够生成相应题类型下随机数数组的类以达到随机获取题目的目的。
RandomUtil.java随机数工具类

/*
 * 随机工具类
 * */
public class RandomUtil {

	/*按照给定范围生成随机数字列表*/
	public static List<Integer> createRandomIntList(int bound){
		List<Integer> list = new ArrayList<Integer>();
		Random random = new Random();
		int rand = 0;
		for(int i = 0;i < bound;i++){
			rand = random.nextInt(bound);
			if(list.contains(rand)){//如果列表中已存在,重新在这一次循环添加随机数
				i--;
				continue;
			}
			list.add(rand);
		}
		return list;
	}
}

在文件设计(数据层设计)时,只描述了缓存数据,现在根据条件(题型)在缓存获取相应的数据,将文件中的数据填充进对象。

/*
 * 问题工厂
 * */
public class QuestionFactory {
private static List<String[]> parameters = FileUtil.readTxtToParameter(Constant.getFileName());
	/*
	 * 获取满足筛选条件的问题
	 * */
	public static List<Question> getQuestionListMatchCondition(String Condition){
		List<Question> list = new ArrayList<Question> ();
		for(String[] parameter : parameters){
			String parameter_3 = parameter[3].trim();
			if(parameter_3.equals(Condition)){
				if(parameter_3.equals(Question.JUDGE_QUESTION) || parameter_3.equals(Question.CHOOSE_QUESTION)){
					Question question = new Question();
					question.setQuestionId(parameter[0]);
					question.setQuestionDesc(parameter[1]);
					question.setAnswerDesc(parameter[2].trim());
					question.setQuestionType(parameter[3]);
					question.setRemark(parameter[4]);
					list.add(question);
				}else{
					Question question = new Question();
					question.setQuestionId(parameter[0]);
					question.setQuestionDesc(parameter[1]);
					question.setAnswerDesc(parameter[2].trim());
					question.setQuestionType(parameter[3]);
					list.add(question);
				}
			}
		}
		return list;
		}
	}

在生成试卷时,首先获取相应题型的问题列表,使用封装的随机数列表生成类RandomUtil的方法,将相应题型按照规定的题目个数随机分配。

/*
	 * 随机获取试题,生成试卷
	 * */
	public static List<Question> createTestPaper(int chooseNumber,int blankNumber,int judgeNumber,int jdNumber){
		List<Question> questionList = getQuestionListMatchCondition(Question.CHOOSE_QUESTION);
		List<Integer> rands = RandomUtil.createRandomIntList(questionList.size()-1);
		List<Question> randQuestionList = new ArrayList<Question>();
		if(questionList.isEmpty() || questionList == null)
			return randQuestionList;
		for(int i=0;i<chooseNumber;i++)
			randQuestionList.add(questionList.get(rands.get(i)));	
		
		questionList = getQuestionListMatchCondition(Question.BLANK_QUESTION);
		rands = RandomUtil.createRandomIntList(questionList.size()-1);
		if(questionList.isEmpty() || questionList == null)
			return randQuestionList;
		for(int i=0;i<blankNumber;i++)
			randQuestionList.add(questionList.get(rands.get(i)));	
		
		questionList = getQuestionListMatchCondition(Question.JUDGE_QUESTION);
		rands = RandomUtil.createRandomIntList(questionList.size()-1);
		if(questionList.isEmpty() || questionList == null)
			return randQuestionList;
		for(int i=0;i<judgeNumber;i++)
			randQuestionList.add(questionList.get(rands.get(i)));	
		
		questionList = getQuestionListMatchCondition(Question.JD_QUESTION);
		rands = RandomUtil.createRandomIntList(questionList.size()-1);
		if(questionList.isEmpty() || questionList == null)
			return randQuestionList;
		for(int i=0;i<jdNumber;i++)
			randQuestionList.add(questionList.get(rands.get(i)));	
		return randQuestionList;
	}

这样一套随机试卷就生成了,下来是练习模式的思路与实现。

  • 练习模式

    练习是自由的,可以选择任意题型答题。在本系统中,使用QuestionFactory的getQuestionListMatchCondition方法来实现,获取相应题型的所有题目。

  • 错题本
    从之前的需求分析可以看出,错题是在考试情况下来统计的,首先设计一个统计类做这样的事情。统计类是用来统计错题的,但是判断问题是否错误是不由统计类来做的,会有相应的逻辑类(或者方法)去处理。

/**
 * 统计类
 * */
public class  Statistics<T> {
	private Set<T> wrongSet = new HashSet<T>();//使用Set可以防止将同一道题重复加入
	public void addWrong(T t){
		wrongSet.add(t);
	}
	public List<T> getWrongQuestionList(){
		List<T> list = new ArrayList<T>();
		Iterator<T> iterator = wrongSet.iterator();
		while(iterator.hasNext())
			list.add(iterator.next());
		return list;
	}
}

之后,可以采用HashMap来实现,键是问题,值作为该题出现的次数,将出现过最多的问题列为重点问题。
由于本系统是以文件来存储数据的,所以统计的错题要写入文件,以便于之后对它们进行操作。在FileUtil.java中添加方法writeParameterToTxt方法实现功能。

public static <T> void writeParameterToTxt(String fileName,List<T> list){
		File writename = new File(fileName);
		if(!writename.exists())
			try {
				writename.createNewFile();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		String txt = "";
		for(T t:list)
			txt = txt+t.toString();
        try {
			writename.createNewFile();
			BufferedWriter out = new BufferedWriter(new FileWriter(writename)); 
	        out.write(txt); // \r\n即为换行 
	        out.flush(); // 把缓存区内容压入文件 
	        out.close(); // 最后记得关闭文件 
		} catch (IOException e) {
			System.out.println("写入文件失败!");
			e.printStackTrace();
		}
	}

错题是存储了,如何知道是什么时候考试错的题呢,可以采用文件名:wrong+"年月日时分秒"来表示是何时生成的错题文件。

/*按日期时间生成文件名*/
	public static String createFileNamebyDate(String Prefix,String Suffix){
	//Prefix前缀:如我wrong,Suffix后缀:如txt
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_hh_mm_ss");
		String fileName = Prefix+sdf.format(date)+"."+Suffix;
		return fileName;	
	}

这样错题就可以被统计并且可以在系统中选择解答。
下篇博文开始界面的实现,谢谢大家观看,博主水平有限还请各位海涵,欢迎大家指正。

猜你喜欢

转载自blog.csdn.net/lMouse_/article/details/87890674