这个作业属于哪个课程 | 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: {
// 结果不能出现负数,所以先判断谁大谁小,将大的赋给number1if(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();}
生成题目中计算过程中不产生负数
点击查看代码
结果不能出现负数,所以先判断谁大谁小,将大的赋给number1if(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: {
// 结果不能出现负数,所以先判断谁大谁小,将大的赋给number1if(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.逐个测试
团队合作心得:
第一次结对项目还是完成的不是很理想,一开始两个人一起讨论思路总是有出入,总是不统一,到后来统一之后,代码方面两个人也是有很多的歧义,总不如一个人来的好,但最终还是求同存异,完成了这一个结对项目,也加强了彼此的团队团结意思。