软件工程——小学生的四则运算
Github项目地址:
题目描述:
通过python语言编写一个能够自动生成小学四则运算的程序(注意是给小学生用的,要是结果出现负数的话他们会很迷茫的!),同时,除了整数外,还要支持真分数的四则运算。
Psp表格:
PSP2.1 |
任务内容 |
计划完成需要的时间(min) |
实际完成需要的时间(min) |
Planning |
计划 |
55 |
60 |
Estimate |
估计这个任务需要多少时间,并规划大致工作步骤 |
25 |
30 |
Analysis |
需求分析 (包括学习新技术) |
40 |
90 |
Design |
具体设计 |
50 |
60 |
Coding |
具体编码 |
420 |
500 |
test |
测试(自我测试,修改代码,提交修改) |
210 |
250 |
Postmortem & Process Improvement Plan |
事后总结 ,并提出过程改进计划 |
40 |
50 |
Summary |
合计 |
830 |
1080 |
ps:本次改版使用java语言
package cn.com.hellowood.spider; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.Scanner; /** * 生成100以内四则运算 * <p> * 要求: * 1. 0-100之间的四则运算 * 2. 3-5个运算符 * 3. 运算过程中不允许出现负数和分数 * 4. 系统输入生成的题数量 * 5. 输出到 result.txt 文件中,文件目录为当前classpath * 6. 文件首行输出学号 * <p> * 使用穷举随机生成题目,会造成大量的栈内存使用,当生成的问题比较多时有可能失败, * 可以考虑根据规则反向拼接生成 */ public class CalculateGenerator { private static ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript"); private static final char PLUS = '+'; private static final char MINUS = '-'; private static final char MULTIPLY = '*'; private static final char DIVIDE = '/'; private static final char DISPLAY_DIVIDE = '÷'; private static final char EQUALS = '='; private static final String DOT = "."; private static final String DOT_REGEX = "\."; private static final char[] operators = {PLUS, MINUS, MULTIPLY, DIVIDE}; private static final Integer MIN_OPERATOR_COUNT = 3; private static final Integer MAX_OPERATOR_COUNT = 5; private static final Integer MIN_CAL_VALUE = 0; private static final Integer MAX_CAL_VALUE = 100; private static final String FILE_NAME = "result.txt"; private static final String STUDENT_NO = "STUDENT_NO"; private static final String NEW_LINE = " "; private static Random random = new Random(); public static void main(String[] args) throws ScriptException { System.out.println("请输入要生成的练习题数量:"); Scanner scanner = new Scanner(System.in); Integer expressionCount = scanner.nextInt(); List<String> expressionList = new ArrayList<>(); for (int i = 0; i < expressionCount; i++) { expressionList.add(getNextExpression()); System.out.println(String.format("正在生成第 %s 道题", i)); } writeExpressionsToFile(expressionList); System.out.println("生成练习题完成"); } /** * 将练习题输出到文件 * * @param expressionList */ private static void writeExpressionsToFile(List<String> expressionList) { File file = new File(FILE_NAME); try (FileWriter fileWriter = new FileWriter(file)) { fileWriter.append(STUDENT_NO); for (String expression : expressionList) { fileWriter.append(NEW_LINE); fileWriter.append(expression); } } catch (IOException e) { e.printStackTrace(); } } /** * 生成练习题 * * @return * @throws ScriptException */ private static String getNextExpression() throws ScriptException { System.out.println("尝试生成下一道题"); // 运算符数量 int operatorCount = random.nextInt(MAX_OPERATOR_COUNT + 1 - MIN_OPERATOR_COUNT) + MIN_OPERATOR_COUNT; StringBuilder expression = new StringBuilder(); // 运算符 List<Character> operatorList = getOperatorList(operatorCount); // 运算数 List<Integer> calValueList = getCalValueList(operatorCount + 1); for (int i = 0; i < operatorList.size(); i++) { Character operator = operatorList.get(i); Integer previousCalValue = calValueList.get(i); Integer nextCalValue = calValueList.get(i + 1); expression.append(previousCalValue); // 除法校验除数不为0且能被整除 if (DIVIDE == operator) { calValueList.set(i + 1, getDivideCalValue(previousCalValue, nextCalValue)); } else if (MINUS == operator) { // 减法校验被减数大于减数 // 当包含小数点时向下取整 String currentResultString = scriptEngine.eval(expression.toString()).toString(); if (currentResultString.contains(DOT)) { currentResultString = currentResultString.split(DOT_REGEX)[0]; } Integer currentResult = Integer.valueOf(currentResultString); while (currentResult < nextCalValue) { nextCalValue = random.nextInt(MAX_CAL_VALUE + 1); } calValueList.set(i + 1, nextCalValue); } expression.append(operator); } expression.append(calValueList.get(operatorCount)); // 计算当前结果是否为正整数 String result = scriptEngine.eval(expression.toString()).toString(); if (result.contains(DOT) || Integer.valueOf(result) < 0) { System.out.println("当前题目不符合要求"); return getNextExpression(); } String currentExpression = expression.append(EQUALS).append(result) .toString() .replaceAll(String.valueOf(DIVIDE), String.valueOf(DISPLAY_DIVIDE)); return currentExpression; } /** * 获取运算符 * * @param operatorCount * @return */ private static List<Character> getOperatorList(int operatorCount) { List<Character> operatorList = new ArrayList<>(); for (int i = 0; i < operatorCount; i++) { Character operator = operators[random.nextInt(operators.length)]; operatorList.add(operator); } return operatorList; } /** * 获取运算数 * * @param calValueCount * @return */ private static List<Integer> getCalValueList(int calValueCount) { List<Integer> calValueList = new ArrayList<>(); for (int i = 0; i < calValueCount; i++) { calValueList.add(random.nextInt(MAX_CAL_VALUE + 1)); } return calValueList; } /** * 当为除法时校验除数不为0且能被整除 * * @param previousCalValue * @param nextCalValue * @return */ private static int getDivideCalValue(Integer previousCalValue, Integer nextCalValue) { if (nextCalValue == 0 || previousCalValue % nextCalValue != 0) { nextCalValue = random.nextInt(MAX_CAL_VALUE) + 1; return getDivideCalValue(previousCalValue, nextCalValue); } return nextCalValue; } }