注:这是一个两人结对开发的项目
开发人员:曾凯 刘雨鑫
一、题目:
结对项目开发-四则运算四
把程序变成一个网页程序,用户通过设定参数,就可以得到各种题目,并可实现在线答题并评判。
二、程序设计思想:
(1)功能分析:
1.这是一个可以在线答题的web版四则运算程序,用户可以通过设点一些参数来生成题目,然后回答这些题目,提交后程序检查回答的正确性,然后将题目的回答情况通过页面显示的方式反馈给用户。
2.由于参数设置导致交互不太方便,用户需要考虑参数如何搭配,由此实现按照年级答题,用户只需要选择年级,就可以生成按照年级配置好一套题
3.用户在做错题后,实现错题的记录和每道错题做错多数次的记录,并且还有错题练习的功能,如果这道错题回答对了,就会将这道错题从错题表中删除
(2)技术分析:
项目的开发思想是MVC,使用的是jsp+Servlet+javaBean的开发模式,在表单校验部分还使用了javaScript
(3)设计步骤分析:
1.按照参数设置答题:
首先用户在页面通过单选,多选或者文本框输入的方式设置参数,然后这些参数的值通过request域传到对应的servlet中,在servlet中接受这些参数的值后调用service层中生成题目的方法已经生成正确答案的方法,然后将题目和正确答案存入记录一个专门的javaBean中, 再将题目通过sassion域传到答题的jsp页面,在答题页面用户通过文本框输入答案后将用户的答案通过request域传到一个检查题目正确性的servlet中,通过调用service层中检查答案正确性的方法将判断后的结果保证到Bean中并通过sassion将结果传到结果jsp页面,在该页面显示回答的情况
2.按照年级设置答题:
包括小学六个年级的四则数学题生成,默认设置的参数有生成题目道数为10道,运算符固定为1位,其中各年级生成的题目参数设置如下:
年级 | 题目要求 |
一年级 | 20以内的加,减 |
二年级 | 100以内的加,减;0-9的乘法,能除尽且除数是1-9的除法 |
三年级 | 两位数乘法,一位数除法,结果带余数 |
四年级 | 三位数乘法,两位数除法,结果带余数 |
五年级 | 分数的加减 |
六年级 | 整数,分数的四则混合运算 |
3.错题回顾:
在检查用户答题正确性时,将答错的题存入一个专门存放错题的javaBean中,检查完成之后就将这个Bean存到错题表中。查看错题时将错题从数据库中读取出来然后用sassion域传到显示错题的jsp,在练习错题时将错题从错题表中取出后用sassion域传到练习错题的jsp页面,在这个页面用户回答之前做错的题,然后将回答的答案同过request请求域传到检查正确性的servlet中,如果回答正确就将该道题从错题表中删除,如果回答错误,则将该道题的回答错误次数加一。
三、核心代码:
在线答题的service类代码:
1 package cn.dmego.service; 2 import java.util.ArrayList; 3 import cn.dmego.dao.MysqlProAnsDao; 4 import cn.dmego.domain.ProAns; 5 import cn.dmego.domain.WrongPro; 6 import cn.dmego.produce.BinaryTree; 7 import cn.dmego.produce.CreatePro; 8 import cn.dmego.produce.ProperFra; 9 10 /************************ 11 * 业务逻辑处理 12 * @author dmego 13 * 14 */ 15 public class ProAnsService { 16 CreatePro cre = new CreatePro(); 17 ProperFra fractin = new ProperFra(); 18 MysqlProAnsDao mpd = new MysqlProAnsDao(); 19 WrongProService wroService = new WrongProService(); 20 /** 21 * 将本次答题情况存入数据库中 22 * @param proBean 23 */ 24 public void saveToDB(ProAns[] proBean){ 25 mpd.resert(); 26 mpd.addAll(proBean); 27 } 28 /** 29 * 检查用户输入的答案是否正确,然后为Bean中的check变量赋值 30 * (-1:答错了;1:答对了) 31 * 如果答错了,将该题存入错题表中 32 * @param proBean 题目对象数组(增加了用户输入的答案) 33 * @return 校验完成的题目对象数组 34 */ 35 public ProAns[] checkAnswer(ProAns[] proBean){ 36 ArrayList<WrongPro> wrongBean = new ArrayList<WrongPro>(); 37 //wrongBean = wroService.showWrong(); 38 for(int i = 0 ; i < proBean.length; i++){ 39 if(proBean[i].getYourAns().equals(proBean[i].getRightAns())) 40 proBean[i].setChecks(1); 41 else{ 42 proBean[i].setChecks(-1); 43 //----将错题存入错题表中---- 44 WrongPro wrongTemp = new WrongPro(); 45 wrongTemp.setProblem(proBean[i].getProblem()); 46 wrongTemp.setRightAns(proBean[i].getRightAns()); 47 wrongTemp.setYourAns(proBean[i].getYourAns()); 48 wrongTemp.setChecks(proBean[i].getChecks()); 49 wrongTemp.setTimes( 1 ); 50 wrongBean.add(wrongTemp); 51 } 52 } 53 wroService.saveWrongToDB(wrongBean); 54 return proBean; 55 } 56 57 /** 58 * 根据用户输入的年级生成题目(按照年级答题) 59 * @param num 默认生成10道题 60 * @param grade 年级 61 * @return 生成好的题目对象数组(包括题目表达式和正确答案) 62 */ 63 public ProAns[] produce(int grade){ 64 mpd.resert(); //重置数据表 65 String rightAns = ""; //程序计算出来的正确答案 66 String problem = ""; //生成的随机表达式 67 int num = 10; 68 ProAns[] proBean = new ProAns[num]; //javaBean数组,用来封装生成的题目和正确答案 69 for(int i = 0; i< num;i++){ 70 String[] array = cre.proArraryG(grade);//生成一个运算符+数字的数组 71 BinaryTree tree = new BinaryTree(array); //把数组作为参数传入生成一棵二叉树的方法 72 rightAns = tree.CalAndVal(grade); //计算正确结果,得到的是假分数 73 if(grade != 3 && grade != 4){ 74 rightAns = fractin.falseToTrue(rightAns); //将结果的假分数化简为带分数 75 } 76 //生成的题目字符串(必须放在计算结果后,因为在计算结果时,该树结构还会因为 负数 或者 除数为0 而变化) 77 problem = tree.toString(); 78 proBean[i] = new ProAns(); //数组中每个元素都必须要new成一个对象否则会抛出空指针异常 79 proBean[i].setId(i+1); 80 proBean[i].setProblem(problem); 81 proBean[i].setRightAns(rightAns); 82 } 83 return proBean; 84 } 85 86 87 /** 88 * 根据用户输入的参数生成题目(按参数答题) 89 * @param hasmd 指定有无乘除法(Y/N) 90 * @param hasfs 指定有无真分数(Y/N) 91 * @param hasgd 指定运算符个数是否固定(Y/N) 92 * @param range 指定运算式取值范围 93 * @param num 指定出题个数 94 * @param synum 指定固定的运算符个数或者最大运算符个数 95 * @return 生成好的题目对象数组(包括题目表达式和正确答案) 96 */ 97 public ProAns[] produce(String hasmd,String hasfs,String hasgd,int range,int num,int synum){ 98 mpd.resert(); //重置数据表 99 String rightAns = ""; //程序计算出来的正确答案 100 String problem = ""; //生成的随机表达式 101 int grade = 0; 102 ProAns[] proBean = new ProAns[num]; //javaBean数组,用来封装生成的题目和正确答案 103 for(int i = 0; i< num;i++){ 104 String[] array = cre.proArrary( range, hasmd, hasfs,hasgd,synum); //生成一个运算符+数字的数组 105 BinaryTree tree = new BinaryTree(array); //把数组作为参数传入生成一棵二叉树的方法 106 rightAns = tree.CalAndVal(grade); //计算正确结果,得到的是假分数 107 rightAns = fractin.falseToTrue(rightAns); //将结果的假分数化简为带分数 108 //生成的题目字符串(必须放在计算结果后,因为在计算结果时,该树结构还会因为 负数 或者 除数为0 而变化) 109 problem = tree.toString(); 110 proBean[i] = new ProAns(); //数组中每个元素都必须要new成一个对象否则会抛出空指针异常 111 proBean[i].setId(i+1); 112 proBean[i].setProblem(problem); 113 proBean[i].setRightAns(rightAns); 114 } 115 return proBean; 116 } 117 }
回顾错题的service类代码:
1 package cn.dmego.service; 2 /************************ 3 * 错题表业务逻辑处理 4 * @author dmego 5 * 6 */ 7 import java.util.ArrayList; 8 9 import cn.dmego.dao.MysqlWrongProDao; 10 import cn.dmego.domain.WrongPro; 11 12 public class WrongProService { 13 MysqlWrongProDao mwp = new MysqlWrongProDao(); 14 /** 15 * 将所有错题显示出来 16 * @return 错题Bean 17 */ 18 public ArrayList<WrongPro> showWrong(){ 19 return mwp.getWrongPro(); 20 } 21 22 /** 23 * 从错题表中删除题 24 * @param wrongBean 25 */ 26 public void wipeWrongInDB(){ 27 mwp.delWrongPro(); 28 } 29 30 /** 31 * 先重置错题表,然后将本次答题中的错题存入错题表中 32 * @param wrongBean 33 */ 34 public void reSaveWrongToDB(ArrayList<WrongPro> wrongBean){ 35 mwp.resertWro(); //先重置 数据表 36 mwp.addWrongPro(wrongBean); 37 } 38 /** 39 * 将本次答题中的错题存入错题表中 40 * @param wrongBean 41 */ 42 public void saveWrongToDB(ArrayList<WrongPro> wrongBean){ 43 mwp.addWrongPro(wrongBean); 44 } 45 46 /** 47 * 检查练习错题时的答题情况, 48 * @param wrongBean 错题集(增加了用户输入的答案) 49 * @return 校验完成的错题集 50 */ 51 public ArrayList<WrongPro> checkWrAnswer(ArrayList<WrongPro> wrongBean){ 52 53 for(int i= 0;i < wrongBean.size(); i++){ 54 if(wrongBean.get(i).getYourAns().equals(wrongBean.get(i).getRightAns())){ 55 wrongBean.get(i).setChecks( 1 ); 56 } 57 else{ 58 //----将该题的答错次数加1---- 59 wrongBean.get(i).setTimes( wrongBean.get(i).getTimes() + 1 ); 60 wrongBean.get(i).setChecks( -1 ); 61 } 62 } 63 return wrongBean; 64 } 65 }
检查在线答题的servlet:
1 package cn.dmego.web; 2 /** 3 * 检查在线答题的答案正确性 4 */ 5 import java.io.IOException; 6 import java.util.Enumeration; 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 import javax.servlet.http.HttpSession; 12 import cn.dmego.domain.ProAns; 13 import cn.dmego.service.ProAnsService; 14 15 public class CheckServlet extends HttpServlet { 16 ProAnsService service = new ProAnsService(); 17 public void doGet(HttpServletRequest request, HttpServletResponse response) 18 throws ServletException, IOException { 19 HttpSession session = request.getSession(); 20 ProAns[] proBean = (ProAns[]) session.getAttribute("proBean"); 21 Enumeration<String> enumeration = request.getParameterNames(); 22 int i = 0; 23 while(enumeration.hasMoreElements()){ 24 String name = (String) enumeration.nextElement(); 25 String yourAns = request.getParameter(name); 26 proBean[i].setYourAns(yourAns); 27 i++; 28 } 29 proBean = service.checkAnswer(proBean); 30 session.setAttribute("proBean", proBean); 31 service.saveToDB(proBean); 32 response.sendRedirect(request.getContextPath()+"/Result.jsp"); //重定向到结果界面 33 } 34 35 public void doPost(HttpServletRequest request, HttpServletResponse response) 36 throws ServletException, IOException { 37 doGet(request, response); 38 } 39 40 }
检查练习错题的servlet:
1 package cn.dmego.web; 2 /** 3 * 检查练习答题的答案正确性 4 */ 5 import java.io.IOException; 6 import java.util.ArrayList; 7 import java.util.Enumeration; 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import javax.servlet.http.HttpSession; 13 import cn.dmego.domain.WrongPro; 14 import cn.dmego.service.WrongProService; 15 16 public class checkWrServlet extends HttpServlet { 17 WrongProService wroService = new WrongProService(); 18 @SuppressWarnings("unchecked") 19 public void doGet(HttpServletRequest request, HttpServletResponse response) 20 throws ServletException, IOException { 21 HttpSession session = request.getSession(); 22 ArrayList<WrongPro> wrongBean = new ArrayList<WrongPro>(); 23 wrongBean = (ArrayList<WrongPro>)session.getAttribute("wrongBean"); 24 Enumeration<String> enumeration = request.getParameterNames(); 25 int i = 0; 26 while(enumeration.hasMoreElements()){ 27 String name = (String) enumeration.nextElement(); 28 String yourAns = request.getParameter(name); 29 wrongBean.get(i).setYourAns(yourAns); 30 i++; 31 } 32 wrongBean = wroService.checkWrAnswer(wrongBean); 33 session.setAttribute("wrongBean", wrongBean); 34 wroService.reSaveWrongToDB(wrongBean); //先重置错题表,再存 35 wroService.wipeWrongInDB(); //然后从错题表中删除答对的题 36 response.sendRedirect(request.getContextPath()+"/pwResult.jsp");//重定向到练习错题的结果界面 37 38 39 } 40 41 public void doPost(HttpServletRequest request, HttpServletResponse response) 42 throws ServletException, IOException { 43 doGet(request, response); 44 } 45 46 }
注:完整的项目源代码已经上传到gitHub,gitHub地址为:https://github.com/dmego/arithmeticWeb
四、项目文件截图,程序运行结果截图:
1.项目工程截图:
2.程序运行结果截图:
五、结对编程的总结体会:
通过这一次结对编写四则运算web版,我体会到了结对开发中的两个人关系的的一步步正规化,从萌芽阶段到创造阶段,从简单生成题目回答题目到有记录错题和练习错题等功能正是两个人通过不断交流和沟通,一起创造ideal的结果。在这个过程中,我学会了如何给人提意见,如果把自己脑海中的想法更加具体的表达给别人。