20194684 + 自动生成四则运算题第一版报告
前提需求
要求:使用C或Java语言完成一个自动生成四则运算试题的程序
软件基本功能如下。
- 自动生成10道100以内的2个操作数的四则运算算式(+ - * /),要求运算结果也在100以内
- 剔除重复算式。2+3 和 2+3 是重复算式,2+3 和 3+2 不属于重复算式
- 题目数量可定制
- 相关参数可控制
- 是否包含乘法和除法
- 操作数数值范围可控
- 操作数是否含负数
- 生成的运算题存储到外部文件result.txt中
需求分析
某幼儿园,老师要每天出30道加减乘除法题目给孩子做。于是,想写一个脚本完成这件事。
功能设计
- 基本功能
- 可配置题目数量
- 支持加减乘除
- 可配置操作数范围
- 支持操作数正负性质
- 扩展功能
- 可输出答案
- 可控制题目中操作数的数量
- 可配置生成的文件路径
- 多线程生成方程, 充分利用每个CPU, 更快
- 完善的错误处理机制
设计实现
项目已开源, 开源地址: https://github.com/Tomotoes/arithmetic-generator
点击此处下载应用。
项目中所用到的库如下:
- 工具: project-lombok
- 包管理器: gradle
- 命令行解析: Apache Commons CLI
- 脚本执行: EvalEx
其中 Main 类, 是我最欣赏的代码片段, 可以体现出本人的设计思想
package com.tomotoes;
import lombok.extern.java.Log;
import lombok.val;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* @author Simon
* @project arithmetic-generator
* @package com.tomotoes
* @date 2019/9/7 15:39
*/
@Log
public class Main {
public static ArrayList<String> results;
public static Generator generator;
public static Option option;
public static List<String> getResult(int amount) {
generator.setArithmetics(new CopyOnWriteArrayList<>());
IntStream.range(0, amount).parallel().forEach(generator::generate);
val arithmetics = generator.getArithmetics();
Map<String, Double> resultsInArithmetics = new ConcurrentHashMap<>(arithmetics.size());
arithmetics.parallelStream()
.filter(arithmetic -> results.parallelStream().noneMatch(result -> result.startsWith(arithmetic)))
.forEach(arithmetic -> resultsInArithmetics.put(arithmetic, Script.eval(arithmetic)));
return resultsInArithmetics.entrySet().parallelStream()
.filter(entry -> entry.getValue() <= option.getBound())
.map(entry -> entry.getKey() + " = " + entry.getValue())
.collect(Collectors.toList());
}
public static void main(String[] args) {
option = Commander.parse(args);
generator = new Generator(option);
results = new ArrayList<>(option.getAmount());
int numberOfAttempts = 0;
val maximumOfAttempts = 30;
while (results.size() != option.getAmount()) {
val result = getResult(option.getAmount() - results.size());
// There may be failures.
// For example, requiring 1000 arithmetics to be generated, and the maximum number of operands is 2 and the maximum number of operands is 2.
// Obviously, this is not possible.
numberOfAttempts = result.size() != 0 ? 0 : numberOfAttempts + 1;
if (numberOfAttempts == maximumOfAttempts) {
log.warning("Unable to generate the specified number of arithmetic.");
return;
}
results.addAll(result);
}
Loggerr logger = new Loggerr(option.getFilePath());
results.forEach(logger::log);
}
}
其中Commander
类用来解析命令行参数, 并配置成 Option
对象
Option
类,是项目的统一配置信息
Generator
类负责生成四则运算方程式
Script
类负责生成方程式结果
而 Logger
类负责打印结果,和保存结果
测试运行
后记
呃.. Java
的轮子真圆~
PSP
PSP2.1 | 任务内容 | 计划完成需要时间(min) | 实际完成需要时间(min) |
---|---|---|---|
Planning | 计划 | 5 | 10 |
Estimate | 估计时间,规划步骤 | 5 | 10 |
Development | 开发 | 30 | 145 |
Analysis | 需求分析 | 5 | 20 |
Coding | 具体编码 | 20 | 120 |
Test | 测试 | 5 | 5 |
Reporting | 报告 | 20 | 40 |
Postmortem&Process Improvement Plan | 总结改进 | 20 | 40 |