实现一个自动生成小学四则运算题目的命令行程序
这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/ |
---|---|
这个作业要求在哪里 | https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230 |
这个作业的目标 | 实现一个自动生成小学四则运算题目的命令行程序 |
项目成员
本结对项目由
-- 3122004589 张逸程
-- 3122004581 萨穆哈尔·艾得力
GiThub:https://github.com/Zhang1chen/3122004589.git
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
Estimate | 估计这个任务需要多少时间 | 300 | 400 |
Development | 开发 | 200 | 130 |
Analysis | 需求分析 (包括学习新技术) | 30 | 60 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 | 10 | 10 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 20 |
Design | 具体设计 | 60 | 50 |
Coding | 具体编码 | 300 | 400 |
Code Review | 代码复审 | 30 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 40 |
Reporting | 报告 | 30 | 30 |
Test Repor | 测试报告 | 60 | 60 |
Size Measurement | 计算工作量 | 20 | 20 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 50 | 50 |
合计 | 1450 | 1320 |
性能分析
代码运行
生成题目数和值的范围,并写进文档
public static void main(String[] args){
// 先测试10个例子看看
int numberQuestions=10;
int range=10;
if(numberQuestions==0){
System.out.println("错误:使用 -n 参数控制生成题目的个数");
return;
}
if(range==0){
System.out.println("错误:使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围");
// 遇到错误直接结束
return;
}
// makeQuestions(numberQuestions,range);
try {
makeQuestions(numberQuestions,range);
}catch (IOException e){
System.out.println("生成题目时发生错误: "+e.getMessage());
}
private static void makeQuestions(int numberQuestions, int range) throws IOException{
// 创建HashSet集合,主要用来去重
Set<String> questions=new HashSet<>();
// 创建写入文档对象
FileWriter exercisesWriters=new FileWriter(EXERCISES_FILE);
FileWriter answersWriters=new FileWriter(ANSWERS_FILE);
String question;
String answer;
while (questions.size()<numberQuestions){
// 生成一个0-3之间的随机数,用于选择运算符
// 0:+
// 1:-
// 2:*
// 3:/
int operation=random.nextInt(4);
// 生成两个0-range之间的随机数,用来参与运算
int number1=random.nextInt(range);
int number2=random.nextInt(range);
switch (operation){
case 0:{
question=number1+"+"+number2+"= ?" ;
// 计算算数之后的值
answer=String.valueOf(number1+number2);
// 判断是否重复,这就用到了HashSet集的特点,无序,不重复,无索引
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
case 1: {
// 结果不能出现负数,所以先判断谁大谁小,将大的赋给number1
if(number2>number1){
int temp=number1;
number1=number2;
number2=temp;
}
question=number1+"-"+number2+"= ?" ;
answer=String.valueOf(number1-number2);
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
case 2: {
question=number1+"*"+number2+"= ?" ;
answer=String.valueOf(number1*number2);
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
case 3: {
if(number2==0||number2==10){
number2=random.nextInt(range)+1;
}
question=number1+"/"+number2+"= ?" ;
answer=String.valueOf(number1/number2);
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
}
}
exercisesWriters.close();
answersWriters.close();
}
生成题目中计算过程中不产生负数
点击查看代码
结果不能出现负数,所以先判断谁大谁小,将大的赋给number1
if(number2>number1){
int temp=number1;
number1=number2;
number2=temp;
}
question=number1+"-"+number2+"= ?" ;
answer=String.valueOf(number1-number2);
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
判断答案的正确与否,并写进文档
点击查看代码
private static boolean isCorrectAnswer(String exercise, String answer) {
String[] exercises=new String[2];
boolean flag=false;
for (int i=0;i<exercise.length();i++){
if(exercise.charAt(i)=='+') {
exercises=exercise.split("\\+");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1+num2==answers) flag=true;
break;
}else if(exercise.charAt(i)=='-'){
exercises=exercise.split("-");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1-num2==answers) flag=true;
break;
} else if (exercise.charAt(i)=='*') {
exercises=exercise.split("\\*");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1*num2==answers) flag=true;
break;
}else if(exercise.charAt(i)=='/'){
exercises=exercise.split("/");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1/num2==answers) flag=true;
break;
}
}
return flag;
}
private static int isNum(String number) {
int num= Integer.parseInt(number);
return num;
}
测试运行
控制生成题目的个数,以及题目数值的范围
并将生成的题目和答案写进文档`
点击查看代码```
`package 博客.结对项目;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class Test1 {
// final定义局部变量,将Exercises.txt和Answers.txt卸载最开头,则所有方法中都可以调用
// 将随机生成的函数也写在最开头
private static final String EXERCISES_FILE="Exercises.txt";
private static final String ANSWERS_FILE="Answers.txt";
private static final Random random=new Random();
public static void main(String[] args) {
// 控制生成题目的个数,以及题目数值的范围
// 并将生成的题目和答案写进文档
// 先测试10个例子看看
int numberQuestions=10;
int range=10;
if(numberQuestions==0){
System.out.println("错误:使用 -n 参数控制生成题目的个数");
return;
}
if(range==0){
System.out.println("错误:使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围");
// 遇到错误直接结束
return;
}
// makeQuestions(numberQuestions,range);
try {
makeQuestions(numberQuestions,range);
}catch (IOException e){
System.out.println("生成题目时发生错误: "+e.getMessage());
}
}
private static void makeQuestions(int numberQuestions, int range) throws IOException{
// 创建HashSet集合,主要用来去重
Set<String> questions=new HashSet<>();
// 创建写入文档对象
FileWriter exercisesWriters=new FileWriter(EXERCISES_FILE);
FileWriter answersWriters=new FileWriter(ANSWERS_FILE);
String question;
String answer;
while (questions.size()<numberQuestions){
// 生成一个0-3之间的随机数,用于选择运算符
// 0:+
// 1:-
// 2:*
// 3:/
int operation=random.nextInt(4);
// 生成两个0-range之间的随机数,用来参与运算
int number1=random.nextInt(range);
int number2=random.nextInt(range);
switch (operation){
case 0:{
question=number1+"+"+number2+"= ?" ;
// 计算算数之后的值
answer=String.valueOf(number1+number2);
// 判断是否重复,这就用到了HashSet集的特点,无序,不重复,无索引
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
case 1: {
// 结果不能出现负数,所以先判断谁大谁小,将大的赋给number1
if(number2>number1){
int temp=number1;
number1=number2;
number2=temp;
}
question=number1+"-"+number2+"= ?" ;
answer=String.valueOf(number1-number2);
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
case 2: {
question=number1+"*"+number2+"= ?" ;
answer=String.valueOf(number1*number2);
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
case 3: {
if(number2==0||number2==10){
number2=random.nextInt(range)+1;
}
question=number1+"/"+number2+"= ?" ;
answer=String.valueOf(number1/number2);
if(!questions.equals(question)){
questions.add(question);
exercisesWriters.write(question+"\n");
answersWriters.write(answer+"\n");
}
break;
}
}
}
exercisesWriters.close();
answersWriters.close();
}
}
从外部当如文件,判断对错个数
点击查看代码
`package 博客.结对项目;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class Test2 {
public static void main(String[] args) {
// 从外部当如文件,判断对错个数
// 找到文件的路径
String exerciseFilePath="D:\\idea\\basic-code\\Exercises.txt";
String answerFilePath="D:\\idea\\basic-code\\Answers.txt";
// 出错显示
if(exerciseFilePath==null||answerFilePath==null){
System.out.println("Myapp.exe -e <exercisefile>.txt -a <answerfile>.txt");
return;
}
// 读取题目和答案
try {
// 调用readFile函数,读取文件,并把他们放到list集合中,方便以后调用
List<String> exercises=readFile(exerciseFilePath);
List<String> answers=readFile(answerFilePath);
// 判断是否正确,并统计
List<Integer> correct=new ArrayList<>();
List<Integer> wrong=new ArrayList<>();
// 1.逐个获取exercises,和answers
// 2.利用分割函数split,将函数分开
// 3.然后调用isCorrect,判断是否相等
for (int i = 0; i < exercises.size(); i++) {
// 获取运算数字前面的式子,去掉等号后面
String exercise=exercises.get(i).split("=")[0];
// 获取答案
String answer=answers.get(i);
// 判断
if(isCorrectAnswer(exercise,answer)){
correct.add(i+1);
}else {
wrong.add(i+1);
}
}
// 将结果写入文件中
writeGradeFile(correct,wrong);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static boolean isCorrectAnswer(String exercise, String answer) {
String[] exercises=new String[2];
boolean flag=false;
for (int i=0;i<exercise.length();i++){
if(exercise.charAt(i)=='+') {
exercises=exercise.split("\\+");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1+num2==answers) flag=true;
break;
}else if(exercise.charAt(i)=='-'){
exercises=exercise.split("-");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1-num2==answers) flag=true;
break;
} else if (exercise.charAt(i)=='*') {
exercises=exercise.split("\\*");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1*num2==answers) flag=true;
break;
}else if(exercise.charAt(i)=='/'){
exercises=exercise.split("/");
int num1=isNum(exercises[0]);
int num2=isNum(exercises[1]);
int answers= Integer.parseInt(answer);
if(num1/num2==answers) flag=true;
break;
}
}
return flag;
}
private static int isNum(String number) {
int num= Integer.parseInt(number);
return num;
}
// 读入文件的重写
private static List<String> readFile(String filePath) throws IOException {
List<String> lines=new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))){
String line;
while ((line = reader.readLine())!=null){
lines.add(line);
}
}
return lines;
}
private static void writeGradeFile(List<Integer> correct, List<Integer> wrong) throws IOException {
try (PrintWriter writer = new PrintWriter("Grade.txt")) {
writer.println("Correct: " + correct.size() + " (" + listToString(correct) + ")");
writer.println("Wrong: " + wrong.size() + " (" + listToString(wrong) + ")");
}
}
private static String listToString(List<Integer> list) {
return String.join(", ", list.toString().replaceAll("[\\[\\]]", ""));
}`
项目小结
1.先生成10个例子,只实现加法
2.逐步完善,实现四则运算
3.随机生成四则运算
4.更改四则运算个数
5.写进文档
6.从外部导入文件路径,判断其中的个数
7.写算法,逐个判断文件中的算数表达式与答案
8.将判断结果写入文档
9.逐个测试
团队合作心得:
第一次结对项目还是完成的不是很理想,一开始两个人一起讨论思路总是有出入,总是不统一,到后来统一之后,代码方面两个人也是有很多的歧义,总不如一个人来的好,但最终还是求同存异,完成了这一个结对项目,也加强了彼此的团队团结意思。