一、前言

      第一次较为正式的尝试着做一个运算软件系统,虽然之前学过一段时间的JAVA,但在操作中还是遇到了重重困难,这篇博客记录了我在完成这项作业时的心路历程,希望我遇到的一些问题能够给大家提供帮助,同时也希望自己在回顾时能够有所感悟。

二、需求分析

      目的是面向小学生设计一款四则运算出题软件。

(1)自动生成10道100以内的2个操作数的四则运算算式(+ - *  /),要求运算结果也在100以内

(2)剔除重复算式。  2 + 3 =    和  2 + 3 =     是重复算式      2 + 3 =   和   3 + 2 =  不属于重复算式

(3)题目数量可定制

(4)相关参数可控制

          是否包含乘法和除法

          操作数数值范围可控(如操作数 在100以内   还是1000以内)

          操作数是否含负数    

(5)生成的运算题存储到外部文件result.txt中

三、设计实现
①使用java语言实现了程序的部分功能实现。

②使用函数之间的调用实现功能

③使用if语句使用逻辑判断

四、功能实现     

     1.编写主函数并通过,命令行接收参数
     2.判断传入的参数是否合法

     3.随机选择题目的数量

     4.选择操作数的个数

     5.选择要生成的操作数的范围

     6.根据产生运算符的个数生成一定运算数的运算式并存入List集合中

     7.当随机产生运算符是“/”时候判断被除数是否能整除除数,并且限制结果是否在0到100之间 如果不能随机产生能被整除的除数

     8.遍历List集合通过函数计算集合中每个运算式的结果

     9.生成的运算题存储到外部文件result.txt中

     10选择输入是否接着生成新的题输入0退出整个系统

五、测试运行

代码部分:

     

  1 package com;
  2 import java.awt.List;
  3 import java.io.File;
  4 import java.io.FileWriter;
  5 import java.io.IOException;
  6 import java.util.ArrayList;
  7 import java.util.Random;
  8 import java.util.Scanner;
  9
 10 import javax.script.ScriptEngine;
 11 import javax.script.ScriptEngineManager;
 12 import javax.script.ScriptException;
 13
 14 public class CalculateGenerator {
 15
 16     private static ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");
 17
 18     private static final char PLUS = '+';
 19     private static final char MINUS = '-';
 20     private static final char MULTIPLY = '*';
 21     private static final char DIVIDE = '/';
 22     private static final char DISPLAY_DIVIDE = '÷';
 23     private static final char EQUALS = '=';
 24     private static final String DOT = ".";
 25     private static final String DOT_REGEX = "\\.";
 26
 27     private static final char[] operators = {PLUS, MINUS, MULTIPLY, DIVIDE};
 28     private static final Integer MIN_OPERATOR_COUNT = 1;
 29     private static final Integer MAX_OPERATOR_COUNT = 1;
 30     private static final Integer MIN_CAL_VALUE = 0;
 31     private static final Integer MAX_CAL_VALUE = 100;
 32
 33     private static final String FILE_NAME = "result.txt";
 34     private static final String STUDENT_NO = "come on";
 35     private static final String NEW_LINE = "\r\n";
 36
 37     private static Random random = new Random();
 38
 39
 40     public static void main(String[] args) throws ScriptException {
 41         while(true){
 42         System.out.println("请输入要生成的练习题数量:输入0退出");
 43         Scanner scanner = new Scanner(System.in);
 44         Integer expressionCount = scanner.nextInt();
 45
 46         if(expressionCount==0){
 47             System.out.println("你已经退出系统");
 48             break;
 49         }
 50         System.out.println("请输入操作数的范围(0-100,1000,10000)");
 51         Integer bb= scanner.nextInt();
 52         System.out.println("请选择操作数量;1(2个),2(3个)");
 53         //Scanner scanner = new Scanner(System.in);
 54         Integer aa= scanner.nextInt();
 55
 56
 57         if(expressionCount<0&&bb<0&&bb>10000&&(aa!=1||aa!=2)){
 58
 59
 60
 61             System.out.println("你的操作有误请重新输入:");
 62         }else{
 63
 64
 65
 66         ArrayList<String> expressionList = new ArrayList<>();
 67         for (int i = 1; i <= expressionCount; i++) {
 68             expressionList.add(getNextExpression(bb,aa));
 69             System.out.println(String.format("正在生成第 %s 道题", i));
 70         }
 71
 72         writeExpressionsToFile(expressionList);
 73         System.out.println("生成练习题完成请到result.txt文件查询");
 74     }
 75 }
 76   }
 77
 78
 79     /**
 80      * 将练习题输出到文件
 81      *
 82      * @param expressionList
 83      */
 84     private static void writeExpressionsToFile(ArrayList<String> expressionList) {
 85         File file = new File(FILE_NAME);
 86         try (FileWriter fileWriter = new FileWriter(file)) {
 87             fileWriter.append(STUDENT_NO);
 88             for (String expression : expressionList) {
 89                 fileWriter.append(NEW_LINE);
 90                 fileWriter.append(expression);
 91             }
 92         } catch (IOException e) {
 93             e.printStackTrace();
 94         }
 95     }
 96
 97     /**
 98      * 生成练习题
 99      *
100      * @return
101      * @throws ScriptException
102      */
103     private static String getNextExpression(int bb,int aa) throws ScriptException {
104         System.out.println("尝试生成下一道题");
105
106
107
108
109         // 运算符数量
110         int operatorCount = random.nextInt(aa + 1 - MIN_OPERATOR_COUNT) + MIN_OPERATOR_COUNT;
111
112         StringBuilder expression = new StringBuilder();
113
114
115         // 运算符
116         ArrayList<Character> operatorList = getOperatorList(operatorCount, aa);
117
118         // 运算数
119         ArrayList<Integer> calValueList = getCalValueList(bb);
120
121         for (int i = 0; i < operatorList.size(); i++) {
122             Character operator = operatorList.get(i);
123
124             Integer previousCalValue = calValueList.get(i);
125             Integer nextCalValue = calValueList.get(i + 1);
126
127                 expression.append(previousCalValue);
128
129
130
131             // 除法校验除数不为0且能被整除
132             if (DIVIDE == operator) {
133                 calValueList.set(i + 1, getDivideCalValue(previousCalValue, nextCalValue));
134             } else if (MINUS == operator) {
135                 // 减法校验被减数大于减数
136                 // 当包含小数点时向下取整
137                 String currentResultString = scriptEngine.eval(expression.toString()).toString();
138                 if (currentResultString.contains(DOT)) {
139                     currentResultString = currentResultString.split(DOT_REGEX)[0];
140                 }
141                 Integer currentResult = Integer.valueOf(currentResultString);
142                 while (currentResult < nextCalValue) {
143                     nextCalValue = random.nextInt(aa + 1);
144                 }
145                 calValueList.set(i + 1, nextCalValue);
146             }
147
148             expression.append(operator);
149         }
150
151         expression.append(calValueList.get(operatorCount));
152
153         // 计算当前结果是否为正整数
154         String result = scriptEngine.eval(expression.toString()).toString();
155
156         if (result.contains(DOT) && Integer.valueOf(result) < 0 ||Integer.valueOf(result) >100  ) {
157             System.out.println("当前题目不符合要求");
158             return getNextExpression(bb,aa);
159         }
160
161         String currentExpression = expression.append(EQUALS).append(result)
162                 .toString()
163                 .replaceAll(String.valueOf(DIVIDE), String.valueOf(DISPLAY_DIVIDE));
164         return currentExpression;
165     }
166
167     /**
168      * 获取运算符
169      *
170      * @param operatorCount
171      * @return
172      */
173     private static ArrayList<Character> getOperatorList(int operatorCount,int a  ) {
174         ArrayList<Character> operatorList = new ArrayList<>();
175         for (int i = 0; i < operatorCount; i++) {
176
177             Character operator = operators[random.nextInt(operators.length)];
178            // operatorList.add(operator);
179             if(a==1 ){
180                 if( (operator.equals(PLUS)&&operator.equals(MINUS)) ){
181                 operatorList.add(operator);
182                 }
183                 else{
184                     Character operator1 = operators[random.nextInt(operators.length)];
185                     operatorList.add(operator1);
186                 }
187             }else{
188                 Character operator1 = operators[random.nextInt(operators.length)];
189                 operatorList.add(operator1);
190             }
191         }
192         return operatorList;
193     }
194
195     /**
196      * 获取运算数
197      *
198      * @param calValueCount
199      * @return
200      */
201     private static ArrayList<Integer> getCalValueList(int calValueCount) {
202         ArrayList<Integer> calValueList = new ArrayList<>();
203
204
205
206         /*System.out.println("请输入操作数的范围(0-100,1000,1000)");
207         Scanner scanner = new Scanner(System.in);
208
209         Integer bb= scanner.nextInt();*/
210
211
212         for (int i = 0; i < calValueCount; i++) {
213
214             calValueList.add(random.nextInt(calValueCount + 1));
215
216         }
217         return calValueList;
218     }
219
220     /**
221      * 当为除法时校验除数不为0且能被整除
222      *
223      * @param previousCalValue
224      * @param nextCalValue
225      * @return
226      */
227     private static int getDivideCalValue(Integer previousCalValue, Integer nextCalValue) {
228         if (nextCalValue == 0 || previousCalValue % nextCalValue != 0) {
229             nextCalValue = random.nextInt(MAX_CAL_VALUE) + 1;
230             return getDivideCalValue(previousCalValue, nextCalValue);
231         }
232         return nextCalValue;
233     }
234 }

   六、psp:

PSP2.1

任务内容

计划共完成需要的时间(min)

实际完成需要的时间(min)

Planning

计划

55

80

·       Estimate

·  估计这个任务需要多少时间,并规划大致工作步骤

50

90

Development

开发

300

360

··       Analysis

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

20

15

·       Design Spec

·  生成设计文档

0

0

·       Design Review

·  设计复审 (和同事审核设计文档)

0

0

·       Coding Standard

  代码规范 (为目前的开发制定合适的规范)

10

10

·       Design

  具体设计

20

35

·       Coding

  具体编码

235

200

·       Code Review

·  代码复审

10

15

·       Test

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

13

15

Reporting

报告

30

40

··       Test Report

·  测试报告

20

15

·       Size Measurement

  计算工作量

0

0

·       Postmortem & Process Improvement Plan

·  事后总结 ,并提出过程改进计划

10

20

02-13 20:44