结对项目-四则运算 “软件”之升级版

一.前提

(1)作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2213

(2)GitHub地址:https://github.com/GVictory/MakeOutQuestionsWithInterface

(3)调试环境:IntelliJ IDEA ,CHORME浏览器

二.作业要求

(1)基本要求

  • 自动生成题目,单个题目最多不能超过4个运算符,操作数小于100。
  • 用户可以输入答案
  • 若用户输入答案正确,则提示正确;若答案错误,则提示错误,并要提示正确答案是多少。

(2)扩展要求

  1. 用户答题结束以后,程序可以显示用户答题所用的时间
  2. 用户可以选择出题的个数(最多不能超过5个题目),答题结束可以显示用户答错的题目个数和答对的题目个数
  3. 用户在第一次答题时,需要用户输入用户名,用户下次启动后,程序需要记住用户前一次输入的用户名 
  4. 程序可以设置答题时间,时间设置为整数,单位为秒,最大不能超过120秒,若超过了答题时间未答题,则提示:时间已到,不能答题。

(3)结对成员

       姓名:李志成 学号:201606110064  博客园地址:https://www.cnblogs.com/97lzc/

       姓名:郭木凯 学号:201606110066  博客园地址:https://www.cnblogs.com/GMUK/

三.时间估算

        结对项目软件过程耗时估计表与统计表

       (时间单位:小时)

PSP2.1

 

Personal Software Process Stages Time Senior Student Time
计划 0.5h 0.5h
估计这个任务需要多少时间 8h 10h
开发 4h 5h
需求分析 (包括学习新技术) 0.5h 0.5h
生成设计文档 0.5h 0.5h
设计复审 0.5h 0h
代码规范 0h 0.5h
具体设计 0.5h 0.5h
具体编码 4h 5h
代码复审 0.5h 0.5h
测试(自我测试,修改代码,提交修改) 0.5h 0.5h
报告 0.5h 0.5h
测试报告 0.5h 0.5h
计算工作量 2h 2h
并提出过程改进计划 1h 1h

个人软件实现阶段

预计时间

实际时间

Planning

计划

1

2

· Estimate

估计这个任务需要多少时间

10

15

Development

开发

10

10

· Analysis

需求分析 (包括学习新技术)

1

1

· Design Spec

生成设计文档

1

1

· Design Review

设计复审

0.5

0.5

· Coding Standard

代码规范

1

1

· Design

具体设计

1

1

· Coding

具体编码

1

1

· Code Review

代码复审

0.5

0.5

· Test

测试(自我测试,修改代码,提交修改)

1

1

Reporting

报告

1

1

·

测试报告

1

1

·

计算工作量

2

2

·

并提出过程改进计划

2

2

 

四:工作详情

    (一)工作:

               李志成:          题目和答案生成,前台题目和答案的渲染。

               郭木凯:          前台设计,换肤,计时。

    (二) 部分功能代码介绍:

 首先是前端页面的实现,通过html,css,JavaScript,jQuery,vue.js编写

复制代码
  1 <!DOCTYPE html>
  2 <html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>志成出题</title>
  6     <script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
  7     <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
  8 </head>
  9 <body style="height: 100%;">
 10 <div style="display: flex;justify-content: center;align-content: center">
 11     <div id="boss" style="display:flex;width: 600px;height: 450px;border: 1px dashed gray; padding: 0px; color: rgb(0, 0, 255); line-height: 1.5 !important;">>
 12         <div style="width: 100px;border-right: 1px solid #bbbbbb;height: 100%;display:flex;align-content: center;justify-content: center">
 13             <div style="font-size: 30px;width: 30px;margin-top: 20px">志成出题</div>
 14         </div>
 15         <div style="width: 100%;height: 100%;display: flex;flex-direction: column">
 16             <div style="width: 100%;height: 90px;display: flex;align-items: flex-end;flex-direction: row;align-items:center;justify-content: space-between">
 17                 <div>
 18                     <div id="selectCount"
 19                          style="display: flex;flex-direction: column;align-items: center;margin-left: 20px">
 20                         <select id="select"
 21                                 style="height:28px;  width:90px;  line-height:28px;  border:1px solid #9bc0dd;  -moz-border-radius:2px;  -webkit-border-radius:2px;  border-radius:2px; ">
 22                             <option value="1">1</option>
 23                             <option value="2">2</option>
 24                             <option value="3">3</option>
 25                             <option value="4">4</option>
 26                             <option value="5" selected>5</option>
 27                         </select>
 28                         <button id="countButton" onclick="getArithmetic()"
 29                                 style="margin-top:10px;border:none;height: 30px;width:60px;color: white;border-radius: 15%;font-size: 9px">
 30                             确定
 31                         </button>
 32                     </div>
 33                 </div>
 34                 <div>
 35                     <div style="display: flex;align-items: flex-start;width: 150px;margin-bottom: 5px">
 36                         <span>所用时间:</span><span id="useTime">0</span><span>秒</span>
 37                     </div>
 38                     <div style="display: flex;align-items: flex-start;width: 150px;margin-top: 5px">
 39                         <span>答题时间:</span><span>120秒</span>
 40                     </div>
 41                 </div>
 42 
 43             </div>
 44             <div id="test"
 45                  style="width: 100%;height: 270px;border-top: 1px solid #bbbbbb;border-bottom:1px solid #bbbbbb;display: flex;flex-direction: column;padding: 30px;box-sizing:border-box">
 46                 <div id="body">
 47                     <div style="margin-bottom: 10px;display: flex;" v-for="(ari,index) in arithmetic">
 48                         <div style="width: 90px">{{ari.question}}</div>
 49                         <span> = </span>
 50                         <input v-bind:id="index" style="border:none;border-bottom: 1px solid #bbbbbb;width: 70px"/>
 51                         <i name="answers" style="margin-right: 25px;margin-left: 25px" v-bind:id="index+10">X</i>
 52                         <div name="answers">
 53                             <span>正确答案:</span>
 54                             <span>{{ari.answer}}</span>
 55                         </div>
 56                     </div>
 57                 </div>
 58             </div>
 59             <div id="result"
 60                  style="width: 100%;height:85px;display: flex;flex-direction: row;justify-content: space-between;align-items: center;padding: 20px;box-sizing: border-box">
 61                 <div>
 62                     <div id="text">
 63                         <span>您答对了<span id="right">3</span>道题,答错了<span id="error">2</span>道题</span><br/>
 64                         <span>答题正确率为<span id="rate">60%</span></span>
 65                     </div>
 66                 </div>
 67                 <div style="display: flex;align-items: flex-end" id="commit">
 68                     <button onclick="commitAnswer()"
 69                             style="border:none;height: 45px;width:100px;color: white;border-radius: 12px;font-size: 17px;margin-right: 5px">
 70                         提交
 71                     </button>
 72                     <button id="skin" onclick="changeSkin()"
 73                             style="border:none;height: 30px;width:40px;color: white;border-radius: 15%;font-size: 9px">
 74                         换肤
 75                     </button>
 76                 </div>
 77             </div>
 78         </div>
 79     </div>
 80 </div>
 81 </body>
 82 <script>
 83     var questions = new Array();
 84     var vue;
 85     var t;
 86 
 87     function getArithmetic() {
 88         var option = $("#select option:selected").text();
 89         $.ajax({
 90             type: 'GET',
 91             url: "/hello?count=" + option,
 92             success: function (data) {
 93                 var jsonData = JSON.stringify(data);
 94                 var obj = JSON.parse(jsonData);
 95                 array = obj;
 96                 for (var p in obj) {//遍历json对象的每个key/value对,p为key
 97                     var ob = {"question": p.toString(), "answer": obj[p]}
 98                     questions.push(ob);
 99                 }
100                 vue = new Vue({
101                     el: '#test',
102                     data: {
103                         arithmetic: questions
104                     }
105                 })
106                 $("#body").show()
107                 $("#selectCount").hide();
108                 $("#commit").show();
109                 $("#text").hide();
110                 $("[name='answers']").hide();
111                 var num = 0;
112                 t = setInterval(function () {
113                     num++;
114                     $("#useTime").text(num)
115                     if (num == 120) {
116                         clearInterval(t);
117                         alert("时间已到,答题结束")
118                         commitAnswer();
119                     }
120                 }, 1000);
121 
122             }
123         });
124     }
125 
126     $(function () {
127         $("#body").hide();
128         $("#commit").hide();
129         $("#text").hide()
130     })
131 
132     function changeSkin() {
133         $("#boss").css("background-color", "#2b2b2b");
134         $("#boss").addClass("changeSkin");
135     }
136 
137     function commitAnswer() {
138         var rightCount = 0;
139         var errorCount = 0;
140         for (var i in questions) {
141             $("#" + i).attr("disabled", "disabled");
142             if (questions[i].answer == $("#" + i).val()) {
143                 var num = parseInt(i) + 10;
144                 $("#" + num.toString()).text("√");
145                 rightCount++;
146             } else {
147                 errorCount++;
148             }
149         }
150         clearInterval(t);
151         $("[name='answers']").show();
152         $("#commit").hide();
153         $("#text").show();
154         $("#right").text(rightCount);
155         $("#error").text(errorCount);
156         $("#rate").text((rightCount / (rightCount + errorCount) * 100) + "%")
157     }
158 </script>
159 <style>
160     .changeSkin {
161         color: #f5a528;
162     }
163 </style>
164 </html>
复制代码

 

  其次是后端控制器代码,如下:

复制代码
1 public class testContraller {
2   @GetMapping("/getArithmetic") 
3   public HashMap<String, Integer> getArithmetic(@RequestParam Integer count) throws JSONException {
4     return new Arithmetic().getArithmetic(count);
5 }
6 }
复制代码

 

  最后是解题函数(此处展示重要部分):

 1     private static String getQuestion(Integer operatorNumber,Integer numberRange){
复制代码
 2         char[] operator = new char[]{'+', '-', '*', '/'};
 3         Random random = new Random();
 4         StringBuilder stringBuilder = new StringBuilder();
 5         for (int operatorIndex = 0; operatorIndex < operatorNumber; operatorIndex++) {
 6             stringBuilder.append(random.nextInt(numberRange+1));
 7             stringBuilder.append(operator[random.nextInt(4)]);
 8         }
 9         stringBuilder.append(random.nextInt(numberRange+1));
10         return stringBuilder.toString();
11     }
12 
13     private static Float getAnswer(String question){
14         Stack<Character> operatorStack=new Stack<Character>();
15         Stack<Float> numberStack=new Stack<Float>();
16         char operatorTemp;
17         StringBuilder numberTemp=new StringBuilder();
18         for (int questionIndex=0;questionIndex<question.length();questionIndex++){
19             char singleChar=question.charAt(questionIndex);
20             if (Character.isDigit(singleChar)){
21                 numberTemp.append(singleChar);
22             }else {
23                 if (!operatorStack.isEmpty()&&operatorStack.getTop()=='*'){
24                     operatorStack.pop();
25                     numberStack.push(numberStack.pop()*Float.valueOf(numberTemp.toString()));
26                 }else if (!operatorStack.isEmpty()&&operatorStack.getTop()=='/'){
27                     operatorStack.pop();
28                     numberStack.push(numberStack.pop()/Float.valueOf(numberTemp.toString()));
29                 }else if(!operatorStack.isEmpty()&&operatorStack.getTop()=='-'){
30                     numberStack.push(-Float.valueOf(numberTemp.toString()));
31                 }else {
32                     numberStack.push(Float.valueOf(numberTemp.toString()));
33                 }
34                 operatorStack.push(singleChar);
35                 numberTemp.delete(0,numberTemp.length());
36             }
37         }
38         if (!operatorStack.isEmpty()&&operatorStack.getTop()=='*'){
39             numberStack.push(numberStack.pop()*Float.valueOf(numberTemp.toString()));
40             operatorStack.pop();
41         }else if (!operatorStack.isEmpty()&&operatorStack.getTop()=='/'){
42             numberStack.push(numberStack.pop()/Float.valueOf(numberTemp.toString()));
43             operatorStack.pop();
44         }else if(!operatorStack.isEmpty()&&operatorStack.getTop()=='-'){
45             numberStack.push(-Float.valueOf(numberTemp.toString()));
46         }else {
47             numberStack.push(Float.valueOf(numberTemp.toString()));
48         }
49         while (!operatorStack.isEmpty()){
50             operatorStack.pop();
51                 numberStack.push(numberStack.pop()+numberStack.pop());
52         }
53         return numberStack.pop();
54     }
复制代码

 

    

五.软件演示

 一进来网页时,网页的模样如下图,主要由五大部分组成,分别是选题数,时间计时,题目,换肤,答题情况,一开始进来时由于题目数未选择,所以时间计时是静止的,题目部分不存在。

  PS:题数只能选择1-5。

 

 

   当选好题数并单击按钮时,选题数部分消失,时间开始计时,题目出现,并且用户可以输入题目的答案并提交。

 

   其次网页还具有换肤功能,当点击换肤时,会改变文字和背景色。

 

   当点击提交时,答题情况部分出现,时间静止,考试结束。

   当超过时间时,弹出提醒,并且输入框此时无法输入,进行与提交一样的操作。

六:结对照片

 

七:收获与感悟

   由于此前已有计算类的实现,所以该作业的难度在于页面的交互以及逻辑的处理,与队友一路做下来,发现所花的时间甚多,特别是调试和测试上,一改再改,与计划的时间相差甚远,至此有感,技术决定效率,效率决定未来。

           

 

posted @ 2018-10-24 19:37  97lzc  阅读(223)  评论(2编辑  收藏  举报