一、前言
第一次较为正式的尝试着做一个运算软件系统,虽然之前学过一段时间的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 |