Author: Xie Weijie 3117004673
I. Github project address: https://github.com/jack-xie460/mytest.git
II. PSP form
PSP2.1 |
Personal Software Process Stages |
Estimated time (minutes) |
Actual time (minutes) |
Planning |
plan |
|
|
· Estimate |
·Estimate how long this task will take |
|
|
Development |
Development |
|
|
· Analysis |
·Needs analysis (including learning new technologies) |
|
|
· Design Spec |
·Generate design documents |
|
|
· Design Review |
·Design review (review design documents with colleagues) |
|
|
· Coding Standard |
·Code specifications (develop appropriate specifications for current development) |
|
|
· Design |
·Specific design |
|
|
· Coding |
·Specific code |
|
|
· Code Review |
·Code review |
|
|
· Test |
·Test (self test, modify code, submit modification) |
|
|
Reporting |
Presentation |
|
|
· Test Report |
·Test report |
|
|
· Size Measurement |
·Calculate workload |
|
|
· Postmortem & Process Improvement Plan |
·Summarize afterwards, and propose process improvement plan |
|
|
Total |
|
|
|
III. efficiency analysis
340ms for generating 10000 questions less than 50
Statistics of right and wrong time of 10000 questions 119ms
Good speed!
IV. implementation process
1. Execute the start method of the Produce class, and the program starts to run. First, call the AmountOfNum class to determine whether the input instruction is correct. If it is correct, the number of questions will be returned.
The BoundOfNum class is called to determine whether the input instruction is correct. If it is correct, the maximum value of the value range is returned.
2. The produce class calls the Expression class to randomly generate an Expression, which can be randomly combined with a number through a subexpression, and a subexpression can be randomly generated through a number
Combine to generate various expressions;
3. the generated expression is passed to the Calculate class. In Calculate, the incoming infix expression is transformed into a suffix expression by calling the houzhuiexp method, and then called.
The calculate method calls the recursion method recursion to calculate the suffix expression and produce the result.
4. Print the generated questions and results to the corresponding documents in a circular manner;
5. Execute the start method in the Judge class to count the right and wrong. First, call the ExtractPath class to determine whether the input instruction is correct. If it is correct, return the title document and
Answer the path of the document, and then count the right and wrong.
6. Collaboration diagram of each class:
V. code description
1. Generate the code of question document and answer document through input instruction:
1 package jieduitest01; 2 3 import java.io.File; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 7 //Console input command, generate questions and answers and put them in corresponding documents 8 public class Produce 9 { 10 11 public static void start() throws IOException 12 { 13 14 File exerciseFile = new File("E:\\java\\Pairing operation\\src\\jieduitest01\\Exercises.txt"); 15 File answerFile = new File("E:\\java\\Pairing operation\\src\\jieduitest01\\Answer.txt"); 16 FileWriter writeToExercisefile =new FileWriter(exerciseFile); 17 FileWriter writeToAnswerfile =new FileWriter(answerFile); 18 19 System.out.println("Please enter the number of questions you want to generate: (for example, the format of generating 10 questions:-n 10)"); 20 while(!AmountOfExp.method()) {} 21 int amount = AmountOfExp.getAmount(); 22 23 System.out.println("Please enter the range of values in the topic you want to generate: (for example, the format of the value is within 10:-r 10)"); 24 while (!BoundOfNum.method()) {} 25 int bound = BoundOfNum.getBound(); 26 27 String expression; 28 //Variable array stores suffix expression for duplicate checking 29 StringBuilder expressionSet = new StringBuilder(); 30 //Cycle print questions and answers 31 for(int i=0;i<amount;i++) 32 { 33 expression =Expression.expression(bound); 34 Calculate cal = new Calculate(expression); 35 String houzhuiExp = cal.houzhuiexp(); 36 37 //The generated suffix expression is the same as the previous one, i.e. the same topic is generated. 38 if(expression.indexOf(houzhuiExp)!=-1) 39 { 40 i--; 41 continue; 42 } 43 44 expressionSet.append(houzhuiExp); 45 String result = cal.calculate(); 46 47 //Negative number generated during calculation 48 if(result.equals("?")) 49 { 50 i--; 51 continue; 52 } 53 54 writeToExercisefile.write(i+1 +" ," + expression + "="+"\n"); 55 writeToAnswerfile.write(i+1 +"," + result + "\n" ); 56 57 } 58 writeToExercisefile.close(); 59 writeToAnswerfile.close(); 60 } 61 62 63 }
1 package jieduitest01; 2 3 import java.util.Scanner; 4 import java.util.regex.Matcher; 5 import java.util.regex.Pattern; 6 7 //Use -n Number of questions generated by parameter control 8 public class AmountOfExp 9 { 10 11 private static int amount; 12 13 public static int getAmount() 14 { 15 return amount; 16 } 17 18 //Judge the input instruction and extract the number of generated questions from the correct input instruction 19 public static boolean method() 20 { 21 22 Pattern p = Pattern.compile("(-)(n)(\\s+)(\\d{1,})"); 23 Scanner scan = new Scanner(System.in); 24 String str = scan.nextLine(); 25 Matcher m = p.matcher(str); 26 boolean bo = m.matches(); 27 String[] sarr ; 28 if(!bo) 29 System.out.println("The format you entered is illegal. Please re-enter it according to the format, for example:-n 10"); 30 else 31 { 32 sarr = str.split("\\s+"); 33 amount = Integer.parseInt(sarr[1]); 34 } 35 return bo; 36 } 37 38 }
1 package jieduitest01; 2 3 import java.util.Scanner; 4 import java.util.regex.Matcher; 5 import java.util.regex.Pattern; 6 7 //Use -r Range of values in parameter control questions 8 public class BoundOfNum 9 { 10 11 private static int bound; 12 13 public static int getBound() 14 { 15 return bound; 16 } 17 18 //Judge the input instruction and extract the range of the value in the topic from the input instruction 19 public static boolean method() 20 { 21 22 Pattern p = Pattern.compile("-r\\s+\\d+"); 23 Scanner scan = new Scanner(System.in); 24 String str = scan.nextLine(); 25 String[] sarr ; 26 Matcher m = p.matcher(str); 27 boolean bo = m.matches(); 28 if(!bo) 29 System.out.println("The format you entered is illegal. Please re-enter it according to the format, for example:-r 10"); 30 else 31 { 32 sarr = str.split("\\s+"); 33 bound = Integer.parseInt(sarr[1]); 34 } 35 return bo; 36 } 37 38 }
1 package jieduitest01; 2 3 import java.util.Random; 4 5 //Build expression 6 public class Expression 7 { 8 9 static Random ran=new Random(); 10 11 public static String expression(int bound) 12 { 13 14 String ziexp1 = null,ziexp2 = null; 15 16 //Probability combined with different subexpressions 17 int i = ran.nextInt(4); 18 switch(i) 19 { 20 21 case 0: 22 ziexp1 = RandomNum.nextNumber(bound); 23 ziexp2 = RandomNum.nextNumber(bound); 24 break; 25 case 1: 26 ziexp1 = RandomNum.nextNumber(bound); 27 ziexp2 = SubExpression.ziepression(bound); 28 break; 29 case 2: 30 ziexp1 = SubExpression.ziepression(bound); 31 ziexp2 = RandomNum.nextNumber(bound); 32 break; 33 case 3: 34 ziexp1 = SubExpression.ziepression(bound); 35 ziexp2 = SubExpression.ziepression(bound); 36 break; 37 default : 38 } 39 40 String operater = operater(); 41 String exp = ziexp1 +" "+operater+" "+ ziexp2; 42 return exp; 43 } 44 45 46 public static String operater() 47 { 48 49 int opnum = ran.nextInt(4); 50 switch(opnum) 51 { 52 53 case 0: 54 return "+"; 55 case 1: 56 return "-"; 57 case 2: 58 return "×"; 59 case 3: 60 return "÷"; 61 } 62 return null; 63 } 64 65 }
2. Code to calculate the result of the generated expression (using Polish expression, i.e. suffix expression):
1 package jieduitest01; 2 3 import java.util.HashMap; 4 import java.util.Stack; 5 6 //Incoming generated expression evaluates to result 7 public class Calculate 8 { 9 //use HashMap Storage operators and their priority 10 HashMap<String,Integer> opls; 11 String str0; 12 13 //Constructor and initializes the priority of each operator 14 public Calculate(String str0) 15 { 16 this.str0 = str0; 17 if(opls==null) 18 { 19 opls = new HashMap<String,Integer>(4); 20 opls.put("+",0); 21 opls.put("-",0); 22 opls.put("×",1); 23 opls.put("÷",1); 24 } 25 } 26 27 //Convert infix expression to suffix expression 28 public String houzhuiexp() 29 { 30 //Out space character 31 String str = str0.replace(" ",""); 32 //Divide infix expression into array 33 String[] strArray = split(str); 34 //Postfix expression stack 35 Stack<String> houzhuiSta = new Stack<String>(); 36 //Temporary stack 37 Stack<String> temStack = new Stack<String>(); 38 39 for(String src:strArray) 40 { 41 //Push operands directly into the stack of suffix expressions 42 if(isNum(src)) 43 houzhuiSta.push("("+src+")"); 44 else //Operands or parentheses 45 { 46 if(temStack.isEmpty()||src.equals("(")) 47 { //"("Or the temporary stack is empty 48 temStack.push(src); 49 } 50 else 51 { 52 if(isLow(temStack.peek(),src)) 53 { 54 if(!src.equals(")")) 55 { ////Priority is lower than the temporary stack head value 56 while((!temStack.isEmpty())&&(isLow(temStack.peek(),src))) 57 { 58 houzhuiSta.push(temStack.pop()); 59 } 60 temStack.push(src); 61 }else//by")" 62 { //The value of temporary stack head is not"(" 63 while((!temStack.isEmpty())&&!(temStack.peek().equals("("))) 64 { 65 houzhuiSta.push(temStack.pop()); 66 } 67 //The value of the temporary stack head is"(" 68 if((!temStack.isEmpty())&&(temStack.peek().equals("("))) 69 { 70 temStack.pop(); 71 } 72 } 73 }else 74 { 75 temStack.push(src); 76 } 77 } 78 } 79 } 80 //Push the remaining value of the temporary stack into the suffix stack 81 while(!temStack.empty()) 82 { 83 houzhuiSta.push(temStack.pop()); 84 } 85 //Convert suffix expression in suffix stack to string return 86 StringBuilder sb1 = new StringBuilder(); 87 for(String str1:houzhuiSta) 88 { 89 sb1.append(str1); 90 } 91 houzhuiSta.clear(); 92 return sb1.toString(); 93 94 } 95 96 //Split expression 97 public String[] split(String str) 98 { 99 100 StringBuilder sb = new StringBuilder(str.length()*2); 101 for(char ch:str.toCharArray()) 102 { 103 104 if(ch=='+'||ch=='-'||ch=='×'||ch=='÷'||ch=='('||ch==')') 105 { 106 sb.append(","); 107 sb.append(ch); 108 sb.append(","); 109 } 110 else 111 { 112 sb.append(ch); 113 } 114 } 115 String src = sb.toString().replaceAll(",{2,}",","); 116 return src.split(","); 117 118 } 119 120 //Split suffix expression 121 public String[] splitHou(String str) 122 { 123 124 StringBuilder sb = new StringBuilder(str.length()); 125 int i = 0; 126 for(char ch:str.toCharArray()) 127 { 128 if(ch=='+'||ch=='-'||ch=='×'||ch=='÷') 129 { 130 sb.append(","); 131 sb.append(ch); 132 } 133 else if(ch=='('||ch==')') 134 { 135 if(i>=1) 136 { 137 sb.append(','); 138 } 139 } 140 else 141 { 142 sb.append(ch); 143 i++; 144 } 145 } 146 String src = sb.toString().replaceAll(",{2,}",","); 147 return src.split(","); 148 149 } 150 151 //Reduced fraction 152 String simplify(String exResult) 153 { 154 SplitFra sp = new SplitFra(exResult); 155 int numberater =sp.getNumberater(); 156 int deno =sp.getDeno(); 157 int comDiv = comDivisor(numberater,deno); 158 numberater /= comDiv; 159 deno /= comDiv; 160 int integer = numberater/deno; 161 int fration = numberater%deno; 162 if(integer == 0) 163 { 164 return fration + "/" + deno; 165 }else if (fration == 0) 166 { 167 return integer+""; 168 }else 169 { 170 return integer + "'" + fration + "/" +deno; 171 } 172 } 173 174 //Finding the greatest common divisor by dividing by rolling 175 int comDivisor(int a,int b) 176 { int c = 1; 177 while(a % b != 0) 178 { 179 c = a % b; 180 a = b; 181 b = c; 182 } 183 return b; 184 } 185 186 //Determine whether it is an operand 187 public boolean isNum(String str) 188 { 189 for (char ch : str.toCharArray()) 190 { 191 if(ch=='+'||ch=='-'||ch=='×'||ch=='÷'||ch=='('||ch==')') 192 return false; 193 } 194 return true; 195 } 196 197 //Compare priorities 198 public boolean isLow(String pop, String str) 199 { 200 if(str.equals(")")) 201 return true; 202 if(opls.get(pop)==null||opls.get(str)==null) 203 return false; 204 return opls.get(pop)>=opls.get(str); 205 } 206 207 //Call recursive method to evaluate result by suffix expression 208 public String calculate() 209 { 210 //Postfix Expression 211 String houhzhuiExp = houzhuiexp(); 212 String[] strs = splitHou(houzhuiexp()); 213 //Call recursion to get results 214 String exResult = recursion(strs); 215 //Negative return from calculation"?" 216 if(exResult.equals("?")) 217 { 218 return "?"; 219 } 220 String result ; 221 //The result is a fraction, simplify 222 if(exResult.contains("/")) 223 { 224 result = simplify(exResult); 225 }else 226 { 227 result = exResult; 228 } 229 return result; 230 } 231 //Recursive Method 232 public String recursion(String[] str) 233 { 234 //Whether there is a negative mark in the calculation process 235 boolean flag = false; 236 int nowlength = str.length; 237 if(str[str.length-1]==" ") 238 { 239 nowlength = str.length-1; 240 }else if(str.length == 1) //If the suffix expression length is 1, the end of recursion will return the result 241 { 242 return str[0]; 243 } 244 String[] nextstr = new String[nowlength-2]; 245 for(int i = 2;i<nowlength;i++) 246 { 247 248 if(str[i].equals("+")||str[i].equals("-")||str[i].equals("×")||str[i].equals("÷")) 249 { 250 String num1 = str[i-2]; 251 String num2 = str[i-1]; 252 String operater = str[i]; 253 String result; 254 switch(operater) 255 { 256 case "+": 257 result = Math.add(num1,num2); 258 break; 259 case "-": 260 result = Math.sub(num1,num2); 261 //Negative number generation 262 if(result.equals("?")) 263 { 264 flag = true; 265 } 266 break; 267 case "×": 268 result = Math.mul(num1,num2); 269 break; 270 case "÷": 271 result = Math.div(num1,num2); 272 break; 273 default : 274 result = null; 275 } 276 //Every time a suffix expression is evaluated, a new suffix expression is built 277 for(int i1=0;i1<nowlength-2;i1++) 278 { 279 if(i1<i-2) 280 { 281 nextstr[i1] = str[i1]; 282 }else if(i1==i-2) 283 { 284 nextstr[i1] = result; 285 }else 286 { 287 nextstr[i1] = str[i1+2]; 288 } 289 } 290 break; 291 } 292 } 293 if(flag) 294 { 295 return "?"; 296 } 297 return recursion(nextstr); 298 } 299 300 }
3. Code for right and wrong statistics of answer documents for corresponding question documents:
1 package jieduitest01; 2 3 import java.io.BufferedReader; 4 import java.io.File; 5 import java.io.FileNotFoundException; 6 import java.io.FileReader; 7 import java.io.FileWriter; 8 import java.io.IOException; 9 10 /* 11 * Enter the command to compare the calculation result of the question file with the answer of the answer file 12 * Print the number and number of correct and wrong questions to the Grade.txt file 13 */ 14 public class Judge 15 { 16 17 public static void start() throws IOException 18 { 19 System.out.println("Please input your operation instruction to make the right and wrong statistics of the answer: (Format:-e <exercisefile>.txt -a <answerfile>.txt)"); 20 while(!ExtractPath.method()) {} 21 String exeFilePath = ExtractPath.getExeFilePath(); 22 String answerFilePath = ExtractPath.getAnswerFilePath(); 23 BufferedReader exe = new BufferedReader(new FileReader(exeFilePath)); 24 BufferedReader answer = new BufferedReader(new FileReader(answerFilePath)); 25 File grade = new File("E:\\java\\Pairing operation\\src\\jieduitest01\\Grade.txt"); 26 FileWriter writeToGrade = new FileWriter(grade); 27 28 String exep = ""; 29 StringBuilder corretNum = new StringBuilder(); 30 StringBuilder wrongNum = new StringBuilder(); 31 int corret = 0; 32 int wrong = 0; 33 int num = 1; 34 while((exep = exe.readLine())!=null) 35 { 36 String anstr = answer.readLine(); 37 String[] exestrs = exep.split(","); 38 String[] anstrs = anstr.split(","); 39 String str = exestrs[1].replaceAll("=", ""); 40 Calculate cal = new Calculate(str); 41 String result = cal.calculate(); 42 String answerstr = anstrs[1]; 43 if(result.equals(answerstr)) 44 { 45 corret++; 46 corretNum.append(num + ","); 47 }else 48 { 49 wrong++; 50 wrongNum.append(num + ","); 51 } 52 num++; 53 54 } 55 writeToGrade.write("Corret: "+corret+"("+corretNum.toString()+")"+"\n"); 56 writeToGrade.write("Wrong: "+wrong+"("+wrongNum.toString()+")"); 57 writeToGrade.close(); 58 exe.close(); 59 answer.close(); 60 } 61 }
1 package jieduitest01; 2 3 import java.io.File; 4 import java.util.Scanner; 5 import java.util.regex.Matcher; 6 import java.util.regex.Pattern; 7 8 /* 9 * Determine whether the input instruction is correct, and extract the target file location from the correct instruction 10 * The title file location can be obtained by getExeFilePath method 11 * The answer file location can be obtained by getAnswerFilePath method 12 */ 13 public class ExtractPath { 14 15 private static String exeFilePath; 16 private static String answerFilePath; 17 18 public static String getExeFilePath() 19 { 20 return exeFilePath; 21 } 22 23 public static String getAnswerFilePath() 24 { 25 return answerFilePath; 26 } 27 28 public static boolean method() 29 { 30 31 Pattern p = Pattern.compile("(-)(e)(\\s+)(\\S+)(\\.)(txt)(\\s+)(-)(a)(\\s+)(\\S+)(\\.)(txt)"); 32 Scanner scan = new Scanner(System.in); 33 String str = scan.nextLine(); 34 Matcher m = p.matcher(str); 35 boolean bo = m.matches(); 36 String[] sarr; 37 if(!bo) 38 { 39 System.out.println("The format you entered is illegal. Please re-enter according to the format:-e <exercisefile>.txt -a <answerfile>.txt)"); 40 }else 41 { 42 sarr = str.split("\\s+"); 43 exeFilePath = sarr[1]; 44 answerFilePath = sarr[3]; 45 File src1 = new File(exeFilePath); 46 File src2 = new File(answerFilePath); 47 if(!(src1.exists()&&src2.exists())) 48 { 49 System.out.println("I can't find the folder you entered!!! Please re-enter"); 50 bo = false; 51 } 52 } 53 return bo; 54 } 55 56 }
Vi. test run
1. Generate 10000 questions, answers and right and wrong statistics within 100 times:
2. Generate 500 questions, answers and right and wrong statistics within 50:
3. Modify the first 11 questions in the answer document and perform the right and wrong statistics separately:
VII. Project summary
Through this assignment, I have experienced the fun of programming, learned a lot of new knowledge and gained a lot.