diff --git a/docs/diagrams/caculator.puml b/docs/diagrams/caculator.puml deleted file mode 100644 index 03a35a49b8..0000000000 --- a/docs/diagrams/caculator.puml +++ /dev/null @@ -1,14 +0,0 @@ -@startuml - -class Calculator { - - Stack numStack - - Stack opStack - + calculate(sb: StringBuilder): double - - calculateTwo(num1: double, num2: double, op: String): double - - toSuffix(formula: ArrayList): ArrayList - - prior(op1: String, op2: String): boolean - - getPriority(op: String): int - - toFormula(sb: StringBuilder): ArrayList -} - -@enduml diff --git a/docs/diagrams/problemgenerator.puml b/docs/diagrams/problemgenerator.puml index 22e6913d64..bd8447a701 100644 --- a/docs/diagrams/problemgenerator.puml +++ b/docs/diagrams/problemgenerator.puml @@ -1,17 +1,36 @@ @startuml package seedu.duke { - class ProblemGenerator { - -DEFAULT_NUMBER: String = "10" - -DEFAULT_MAX_DIGITS: String = "2" - -DEFAULT_OPERATORS: String = "+-*/" - -PROBLEM_FORM: String - -in: Scanner - +typeChoose(): Test - -generate(parameter: HashMap): Test - +parseCommand(command: String): HashMap - -defaultOptions(command: String, options: HashMap): void - } + + + class ProblemGenerator { + - MINIMUM_NUMBER: int + - MAXIMUM_NUMBER: int + - MINIMUM_DIGIT: int + - MAXIMUM_DIGITS: int + - MINIMUM_LENGTH: int + - VALID_OPERATORS: String + - MAXIMUM_LENGTH: int + - DEFAULT_NUMBER: String + - DEFAULT_MAX_DIGITS: String + - DEFAULT_OPERATORS: String + - DEFAULT_LENGTH: String + + parseCommand(command: String): HashMap + - defaultOptions(options: HashMap): HashMap + + typeChoose(command: String): Test + - checkValidity(parameter: HashMap): HashMap + - checkOperations(parameter: HashMap) + - checkLength(parameter: HashMap) + - checkMaxDigit(parameter: HashMap) + - checkNumber(parameter: HashMap) + - generate(parameter: HashMap): Test + - buildFormula(length: int, max: int, descriptionBuilder: StringBuilder, operations: ArrayList) + - getOperations(op: String): ArrayList + - division_check(sb: StringBuilder): StringBuilder + } + + + class Test { -operators: String @@ -34,6 +53,16 @@ package seedu.duke { class Ui { +missingMessage(option: String): void } + class Calculator { + - Stack numStack + - Stack opStack + + calculate(sb: StringBuilder): double + - calculateTwo(num1: double, num2: double, op: String): double + - toSuffix(formula: ArrayList): ArrayList + - prior(op1: String, op2: String): boolean + - getPriority(op: String): int + - toFormula(sb: StringBuilder): ArrayList + } } @@ -42,5 +71,5 @@ Test --> Problem: contains ProblemGenerator --> Test: create ProblemGenerator --> Test: generate ProblemGenerator --> Ui: displayMessage - +ProblemGenerator --> Calculator : calculate @enduml diff --git a/docs/heinzhuang.md b/docs/heinzhuang.md new file mode 100644 index 0000000000..a7b748c220 --- /dev/null +++ b/docs/heinzhuang.md @@ -0,0 +1,5 @@ +# Heinz Huang + +GitHub username: Geinzit + +Professional Gamer. Amateur Coder. \ No newline at end of file diff --git a/recordList.txt b/recordList.txt index e69de29bb2..4fb32ff84e 100644 --- a/recordList.txt +++ b/recordList.txt @@ -0,0 +1,9 @@ +2024-04-15 17:59:04 0.0 0.0 60559209 user-DIY 463d_,23.0 +2024-04-15 18:01:52 31.57894736842105 0.0 78253069 auto-generated 87-58,29.0 90*60,5400.0 65/5,13.0 71*50,3550.0 43+46,89.0 32+56,88.0 43*81,3483.0 75/8,9.375 30+52,82.0 68/9,7.556 +2024-04-15 18:03:47 3.75 1.0 60559209 user-DIY 463d_,23.0 +2024-04-15 18:14:21 0.0 0.0 1234776916 user-DIY 2][,343.0 +2024-04-15 18:14:49 3.333333333333333 1.0 1234776916 user-DIY 2][,343.0 +2024-04-15 22:21:39 54.54545454545455 0.0 -76978608 auto-generated 92*88,8096.0 63-56,7.0 49-12,37.0 24-57,-33.0 86-77,9.0 46-37,9.0 22+23,45.0 84-14,70.0 40/1,40.0 72*73,5256.0 +2024-04-15 22:33:39 100.0 0.0 -76978608 auto-generated 59+28,87.0 9/8,1.125 67-86,-19.0 18-28,-10.0 47*52,2444.0 10/8,1.25 18-93,-75.0 2/3,0.667 19/7,2.714 89*10,890.0 +2024-04-15 22:36:06 120.0 0.0 -76978608 auto-generated 57*40,2280.0 12/2,6.0 21*17,357.0 38+16,54.0 84+34,118.0 23+86,109.0 85+57,142.0 71+15,86.0 3*30,90.0 50/6,8.333 +2024-04-15 22:38:40 300.0 0.0 -76978608 auto-generated 96*82,7872.0 16+77,93.0 98+9,107.0 25/6,4.167 17+66,83.0 44+36,80.0 86/8,10.75 19-81,-62.0 45-54,-9.0 78/7,11.143 diff --git a/src/main/java/seedu/duke/Calculator.java b/src/main/java/seedu/duke/Calculator.java index c98422caec..5eb1930cf4 100644 --- a/src/main/java/seedu/duke/Calculator.java +++ b/src/main/java/seedu/duke/Calculator.java @@ -80,6 +80,7 @@ private static String getExplanation(double num1, double num2, String op, double } alignedProblem = builder.toString(); + } return start + alignedProblem + "\n"; } diff --git a/src/main/java/seedu/duke/Checker.java b/src/main/java/seedu/duke/Checker.java index 631b48778e..9491ac1c99 100644 --- a/src/main/java/seedu/duke/Checker.java +++ b/src/main/java/seedu/duke/Checker.java @@ -15,7 +15,7 @@ public class Checker { private long time; public Checker(Test test) { - assert test != null : "You must intialize the checker with a test!"; + assert test != null : "Input null test!"; this.userAnswer = new String[test.getNumber()]; this.test = test; this.isCorrect = new Boolean[test.getNumber()]; @@ -25,39 +25,42 @@ public Checker(Test test) { } public static void showExplanation(Problem problem) { - assert problem != null : "You must give a problem to show the explanation!"; String explanations = problem.getExplanations(); Ui ui = new Ui(""); ui.print("The explanation of the problem: " + problem.solved()); ui.print("Let us caculate it step by step:"); ui.print(explanations); - + ui.print("From all the steps above, we can get the answer: " + problem.solved()+"\n"); } Boolean checkCorrectness(Problem problem, double answer) { - if(Math.abs(problem.getAnswer() - answer) < 0.01) { - return true; - } - return false; + return Math.abs(problem.getAnswer() - answer) < 0.01; } void getUserAnswer() { long startTime = System.currentTimeMillis(); - ui.startAnswerTest(); - String userInput = ui.readCommand(); - + ui.print( + "you can type \"exit\" to quit the test when answering the question..."); + // + boolean isQuit = false; for (int i = 0; i < test.getNumber(); i++) { + + if (isQuit){ + break; + } + Problem problem = test.getProblem().get(i); ui.print(problem.unsolved()); - userInput = ui.readCommand(); + String userInput = ui.readCommand(); userAnswer[i] = userInput; double answer = Double.NEGATIVE_INFINITY; + boolean isValid = false; if (userInput.equals("exit")) { - ui.exitTest(); + ui.print("Exit the test! All the test not finished will be marked as wrong!"); break; } while (!isValid) { @@ -65,14 +68,22 @@ void getUserAnswer() { try { answer = Double.parseDouble(userInput); isValid = true; + } catch (NumberFormatException e) { - + ui.print("Invalid Input, please enter a number"); ui.print(problem.unsolved()); userInput = ui.readCommand(); - + if (userInput.equals("exit")) { + ui.print("Exit the test! All the test not finished will be marked as wrong!"); + isQuit = true; + break; + } } } + if (isQuit){ + break; + } if (checkCorrectness(problem, answer)) { correctNumber++; @@ -86,12 +97,11 @@ void getUserAnswer() { // hand with time and acc long endTime = System.currentTimeMillis(); accuracy = (double) correctNumber / test.getNumber(); - // millisecond to second + //millisecond to second this.time = (endTime - startTime) / 1000; for (int i = 0; i < test.getNumber(); i++) { if (isCorrect[i] = false) { - Problem problem = test.getProblem().get(i); - wrongProblem.add(problem); + wrongProblem.add(test.getProblem().get(i)); wrongAnswer.add(userAnswer[i]); } } diff --git a/src/main/java/seedu/duke/ProblemGenerator.java b/src/main/java/seedu/duke/ProblemGenerator.java index 4b727d497b..464c1a8bf2 100644 --- a/src/main/java/seedu/duke/ProblemGenerator.java +++ b/src/main/java/seedu/duke/ProblemGenerator.java @@ -44,8 +44,6 @@ public static HashMap parseCommand(String command) { break; } } - - //defaultOptions(command, options); return options; } @@ -78,23 +76,54 @@ public Test typeChoose(String command) { private HashMap checkValidity(HashMap parameter) { + checkNumber(parameter); + + checkMaxDigit(parameter); + + checkLength(parameter); + checkOperations(parameter); + return parameter; + + } + + private static void checkOperations(HashMap parameter) { + String op = parameter.get("operators"); + if (op != null) { + for (char ch : op.toCharArray()) { + if (VALID_OPERATORS.indexOf(ch) == -1) {// neither + - * or / + System.out.println("Operators should only be chosen from + - * and /!"); + parameter.remove("operators"); + Ui.invalidMessage("operators"); + break; + } + } + } else { + parameter.remove("operators"); + Ui.invalidMessage("operators"); + } + + } + + private static void checkLength(HashMap parameter) { try { NumberFormatException e = new NumberFormatException(); - int number = Integer.parseInt(parameter.get("number")); - if (number < MINIMUM_NUMBER) { - System.out.println("Number of problems should be at least 1!"); - + int length = Integer.parseInt(parameter.get("length")); + if (length < MINIMUM_LENGTH) { + System.out.println("Number of operands should be at least 2!"); throw e; } - if (number > MAXIMUM_NUMBER) { - System.out.println("Number of problems should be at most 100!"); + if (length > MAXIMUM_LENGTH) { + System.out.println("Number of operands should be at most 10!"); throw e; + } } catch (NumberFormatException e) { - parameter.remove("number"); - Ui.invalidMessage("number"); + parameter.remove("length"); + Ui.invalidMessage("length"); } + } + private static void checkMaxDigit(HashMap parameter) { try { NumberFormatException e = new NumberFormatException(); int maxDigit = Integer.parseInt(parameter.get("maximumDigits")); @@ -110,39 +139,25 @@ private HashMap checkValidity(HashMap parameter) parameter.remove("maximumDigits"); Ui.invalidMessage("maximum of digits"); } + } + private static void checkNumber(HashMap parameter) { try { NumberFormatException e = new NumberFormatException(); - int length = Integer.parseInt(parameter.get("length")); - if (length < MINIMUM_LENGTH) { - System.out.println("Number of operands should be at least 2!"); + int number = Integer.parseInt(parameter.get("number")); + if (number < MINIMUM_NUMBER) { + System.out.println("Number of problems should be at least 1!"); + throw e; } - if (length > MAXIMUM_LENGTH) { - System.out.println("Number of operands should be at most 10!"); + if (number > MAXIMUM_NUMBER) { + System.out.println("Number of problems should be at most 100!"); throw e; - } } catch (NumberFormatException e) { - parameter.remove("length"); - Ui.invalidMessage("length"); - } - - String op = parameter.get("operators"); - if (op != null) { - for (char ch : op.toCharArray()) { - if (VALID_OPERATORS.indexOf(ch) == -1) {// neither + - * or / - System.out.println("Operators should only be chosen from + - * and /!"); - parameter.remove("operators"); - Ui.invalidMessage("operators"); - break; - } - } - } else { - parameter.remove("operators"); - Ui.invalidMessage("operators"); + parameter.remove("number"); + Ui.invalidMessage("number"); } - return parameter; } private Test generate(HashMap parameter) { @@ -153,28 +168,10 @@ private Test generate(HashMap parameter) { String op = parameter.get("operators"); int length = Integer.parseInt(parameter.get("length")); + Test test = new Test(op, maxDigit, number, length); - ArrayList operations = new ArrayList<>(); - - if (op.contains("+")) { - operations.add("+"); - } - if (op.contains("-")) { - operations.add("-"); - } - if (op.contains("*")) { - operations.add("*"); - } - if (op.contains("/")) { - operations.add("/"); - } - + ArrayList operations = getOperations(op); - Test test = new Test(op, maxDigit, number, length); - - Ui.showLine(); - System.out.println("Generating " + number + " problems, you can preview them below:"); - for (int i = 0; i < number; i++) { @@ -183,15 +180,7 @@ private Test generate(HashMap parameter) { String explanations; int max = (int) Math.pow(MAXIMUM_LENGTH, maxDigit); - for (int j = 0; j < length; j++) { - int tempRandomNumber = (int) (Math.random() * max); - descriptionBuilder.append(tempRandomNumber); - - if (j != length - 1) { - String tempRandomOperator = operations.get((int) (Math.random() * operations.size())); - descriptionBuilder.append(tempRandomOperator); - } - } + buildFormula(length, max, descriptionBuilder, operations); descriptionBuilder = division_check(descriptionBuilder); Calculator calculator = new Calculator(); @@ -207,6 +196,36 @@ private Test generate(HashMap parameter) { return test; } + private static void buildFormula(int length, int max, StringBuilder descriptionBuilder, ArrayList operations) { + for (int j = 0; j < length; j++) { + int tempRandomNumber = (int) (Math.random() * max); + descriptionBuilder.append(tempRandomNumber); + + if (j != length - 1) { + String tempRandomOperator = operations.get((int) (Math.random() * operations.size())); + descriptionBuilder.append(tempRandomOperator); + } + } + } + + private static ArrayList getOperations(String op) { + ArrayList operations = new ArrayList<>(); + + if (op.contains("+")) { + operations.add("+"); + } + if (op.contains("-")) { + operations.add("-"); + } + if (op.contains("*")) { + operations.add("*"); + } + if (op.contains("/")) { + operations.add("/"); + } + return operations; + } + private StringBuilder division_check(StringBuilder sb) { // change the divisor to a non-zero one-digit number