四则运算题目自动生成程序
一.github地址
项目参与者: 罗泉水 3118005101
陈鸿畅 3118005087
二.PSP表格(预期)
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | |
Estimate | 估计这个任务需要多少时间 | 30 | |
Development | 开发 | 13 | |
Analysis | 需求分析 (包括学习新技术) | 60 | |
Design Spec | 生成设计文档 | 0 | |
Design Review | 设计复审 (和同事审核设计文档) | 0 | |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | |
Design | 具体设计 | 180 | |
Coding | 具体编码 | 1000 | |
Code Review | 代码复审 | 30 | |
Test | 测试(自我测试,修改代码,提交修改) | 30 | |
Reporting | 报告 | 120 | |
Test Report | 测试报告 | 60 | |
Size Measurement | 计算工作量 | 30 | |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | |
总计 | 1460 |
三.性能测试
- 分析:字符数组和字符串数据占用了大量的内存。对象的实例化多,耦合性很大。
四.设计实现过程
-
编程语言
JAVA
-
解题思路
- 主函数引导用户输入创建题目的条件。
- 主函数实例化ArithmeticGen类(四则运算获得方法),以获得四则运算题目。
- ArithmeticGen中实例化Expression(表达式实体类),获得用户想要个数的算术表达式。
- Expression中由Fraction(分数实体类)构成,关于分数的操作放在FractionUtil(分数操作工具类)中。
- ArithmeticGen获得很多的Expression(表达式)后,通过FileUtil(文件IO工具类)将题目和答案打印在文件中。
- 用户在题目文件输入答案后,通过Correcting(批改类)批改答案,并将答题情况打印在文件中。
-
项目结构
- Entity实体类
- Expression算术表达式实体类
- Fraction分数实体类
- Service服务类
- ArithmeticGen创建四则运算题目服务类
- Correcting批改答案服务类
- Util工具类
- FileUtil文件工具类
- Fraction分数工具类
- 主函数main
- Entity实体类
五.关键代码
-
主函数主要部分
ArithmeticGen Gen = new ArithmeticGen(numRange); TwoTuple<String,String> twoTuple = Gen.expBuilder(expAmount); FileUtil.write("exercise.txt", twoTuple.first); FileUtil.write("answer.txt", twoTuple.second); System.out.println("出题完毕,请在题目文件中输入您的答案并保存文件"); System.out.println(); System.out.println("完成答题后,输入1批改答案,输入其他退出程序"); Scanner scanner = new Scanner(System.in); if(scanner.nextLine().equals("1")){ try { Correcting.correctAnswer(); System.out.println("批改完成,请在“Grade.txt”文件中查看答题情况"); } catch (Exception e) { e.printStackTrace(); } }else { System.exit(0); }
-
ArithmeticGen类中创建多条表达式的方法
public TwoTuple<String,String> expBuilder(int expAmount) {
StringBuilder exptext = new StringBuilder();
StringBuilder anstext = new StringBuilder();
for(int i=1; i<=expAmount; i++) {
Expression expBean = new Expression();
int optNum = random.nextInt(3)+1;
for(int n = 0; n < optNum; n++){
expBean=createExp(expBean);
}
exptext.append("第" + i + "题: " + expBean.getExpression() + " 请作答:"+"\n");
anstext.append("第" + i + "题: " + expBean.getFraction() + "\n");
}
return tuple(exptext.toString(), anstext.toString());
}
-
创造一条表达式的方法
private Expression createExp(Expression expBean1) { Expression expBean=new Expression(); Boolean flagZero = false; Fraction f2= FractionUtil.CreatFraction(num); //随机设置f2自然数 if(random.nextBoolean()){ f2.setDenominator(1); } char opt = '+'; switch(random.nextInt(4)) { case 0 : opt = '+'; break; case 1 : opt = '-'; break; case 2 : opt = '*'; break; case 3 : opt = '÷'; break; default: break; }; if((expBean1.getExpression()).equals("")) { Fraction f1= FractionUtil.CreatFraction(num); if(f2.getNumerator()==0&&opt=='÷') opt = '+'; if(!f1.greater(f2)&&opt=='-') { expBean.setExpression( "" + f2 + opt + f1); expBean.setFraction(FractionUtil.calculate(f2, f1, opt)); }else { expBean.setExpression( "" + f1 + opt + f2); expBean.setFraction(FractionUtil.calculate(f1, f2, opt)); } }else { if(random.nextBoolean()) { if(f2.getNumerator()==0&&opt=='÷') opt = '+'; if(!expBean1.getFraction().greater(f2)&&opt=='-') { expBean.setExpression("" + f2 + opt + "(" + expBean1 + ")"); expBean.setFraction(FractionUtil.calculate(f2, expBean1.getFraction(), opt)); }else { expBean.setExpression( "(" + expBean1 + ")" + opt + f2); expBean.setFraction(FractionUtil.calculate(expBean1.getFraction(), f2, opt)); } }else { if(expBean1.getFraction().getNumerator()==0&&opt=='÷') opt = '+'; if(expBean1.getFraction().greater(f2)&&opt=='-') { expBean.setExpression( "(" + expBean1 + ")" + opt + f2); expBean.setFraction(FractionUtil.calculate(expBean1.getFraction(), f2, opt)); }else { expBean.setExpression("" + f2 + opt + "(" + expBean1 + ")"); expBean.setFraction(FractionUtil.calculate(f2, expBean1.getFraction(), opt)); } } } return expBean; }`
-
批改答案方法correctAnswer()
public static void correctAnswer() throws Exception{ String lineAns; String lineExe; int test = 1; ArrayList<Integer> listCorrect = new ArrayList<>(); ArrayList<Integer> listWrong = new ArrayList<>(); BufferedReader brExe = new BufferedReader(new FileReader("exercise.txt")); BufferedReader brAns = new BufferedReader(new FileReader("answer.txt")); //BufferedWriter bw = new BufferedWriter(new FileWriter("Grade.txt")); PrintStream bw = new PrintStream(new FileOutputStream("Grade.txt")); while ((lineAns = brAns.readLine()) != null){ lineAns = lineAns.split(" ")[1]; lineExe = brExe.readLine(); String [] exerSplit = lineExe.split(":"); if(exerSplit.length == 3){ lineExe = exerSplit[2]; } if(lineAns.equals(lineExe)){ listCorrect.add(test++); }else { listWrong.add(test++); } } bw.print("Correct:" + listCorrect.size() + "("); if(listCorrect.size() == 0){ bw.print(")"); }else{ for(int i = 0; i < listCorrect.size(); i++){ bw.print(listCorrect.get(i)); if(i == listCorrect.size()-1){ bw.print(")"); }else { bw.print(","); } } } bw.println(); bw.print("Wrong:" + listWrong.size() + "("); if(listWrong.size() == 0){ bw.print(")"); }else { for (int i = 0; i < listWrong.size(); i++) { bw.print(listWrong.get(i)); if (i == listWrong.size() - 1) { bw.print(")"); } else { bw.print(","); } } } bw.close(); brAns.close(); brExe.close(); }
六.功能测试
-
测试一
-
exercise.txt
-
answer.txt
-
Grade.txt
-
测试二
-
exercise.txt
-
answer.txt
-
Grade.txt
-
测试三
-
exercise.txt
-
answer.txt
-
Grade.txt
-
测试四
-
exercise.txt
-
answer.txt
-
Grade.txt
七.PSP表格(完成)
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 15 |
Estimate | 估计这个任务需要多少时间 | 30 | 15 |
Development | 开发 | 1310 | 1410 |
Analysis | 需求分析 (包括学习新技术) | 60 | 100 |
Design Spec | 生成设计文档 | 0 | 0 |
Design Review | 设计复审 (和同事审核设计文档) | 0 | 0 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 30 |
Design | 具体设计 | 180 | 210 |
Coding | 具体编码 | 1000 | 1020 |
Code Review | 代码复审 | 30 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 20 |
Reporting | 报告 | 120 | 145 |
Test Report | 测试报告 | 60 | 120 |
Size Measurement | 计算工作量 | 30 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 15 |
总计 | 1460 | 1570 |
八.总结
- 一定要规范。命名规范、分包规范、结构规范。
- 和他人合作一定要及时讨论好,多交流多沟通。
- 熟能生巧。打码少了,知识点就生疏了;生疏了,效率便会很低。