diff --git a/docs/assets/images/sd_old_version.png b/docs/assets/images/sd_old_version.png new file mode 100644 index 0000000000..eb6cd228cb Binary files /dev/null and b/docs/assets/images/sd_old_version.png differ diff --git a/docs/assets/images/sequenceDiagram.png b/docs/assets/images/sequenceDiagram.png index eb6cd228cb..14645fce0f 100644 Binary files a/docs/assets/images/sequenceDiagram.png and b/docs/assets/images/sequenceDiagram.png differ diff --git a/docs/diagrams/sequence_diagram.pum b/docs/diagrams/sequence_diagram.pum new file mode 100644 index 0000000000..f55ff92cff --- /dev/null +++ b/docs/diagrams/sequence_diagram.pum @@ -0,0 +1,70 @@ +@startuml +actor User + +participant ":Ui" as Ui +participant ":Parser" as Parser +participant ":ProblemGenerator" as ProblemGenerator +participant "test:Test" as Test +participant ":Checker" as Checker +participant ":Storage" as Storage +participant "problem:Problem" as Problem +participant ":Calculator" as Calculator + + + +User -> Duke: start +activate Duke +Duke -> Storage: readFile() +activate Storage +Storage -> Storage: read file +deactivate Storage +deactivate Duke + +Duke -> Ui: greet() +activate Ui +Ui -> Ui: Display greeting message +deactivate Ui + +Duke -> Ui: readCommand() +activate Ui +Ui --> Duke: return command +deactivate Ui + +loop until exit command + Duke -> Parser: parse(command, Ui) + activate Parser + Parser -> ProblemGenerator: typeChoose(command) + activate ProblemGenerator + ProblemGenerator -> ProblemGenerator: parseCommand(command) + ProblemGenerator -> ProblemGenerator: defaultOptions(command, options) + ProblemGenerator -> ProblemGenerator: generate(parameter) + deactivate ProblemGenerator + Parser -> Calculator: calculate(descriptionBuilder) + activate Calculator + Calculator -> Calculator: toFormula(sb) + Calculator -> Calculator: toSuffix(formula) + Calculator -> Calculator: calculateTwo(num1, num2, op) + deactivate Calculator + Parser -> Test: addToTest(p) + activate Test + Test -> Problem: Problem(description, answer) + deactivate Test + Parser -> Checker: new Checker(test) + activate Checker + Checker -> Checker: getUserAnswer() + Checker -> Checker: checkCorrectness(problem, answer) + deactivate Checker + deactivate Parser +end + +Duke -> Storage: writeFile() +activate Storage +Storage -> Storage: write records to file +deactivate Storage + +Duke -> Ui: exit() +activate Ui +Ui -> Ui: Display exit message +deactivate Ui + +@enduml \ No newline at end of file diff --git a/docs/team/yzhanglp.md b/docs/team/yzhanglp.md index 3804235b14..cd941314ed 100644 --- a/docs/team/yzhanglp.md +++ b/docs/team/yzhanglp.md @@ -1,13 +1,23 @@ -# Yuhao ZHANG +# Yuhao ZHANG's Project Portfolio Page ## Overview of `MathGenius` **`MathGenius`** is a user-friendly application that provides a platform to enhance your equation-solving abilities. Whether you're a student learning calculation, a math enthusiast looking to sharpen your skills, or a teacher preparing for exams/lessons, this application is here to support you. ## Summary of Contribution -[**link to the code**](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=yzhanglp&breakdown=true) -In the project `MathGenius`, I am in conduct of implement the `checker` part, which is use to check the user's answer, record the time and accuracy, as well as generate the explanation of the questions. -In the `UserGuide`,I am in conduct of writing the introduction and some parts of the guidance. -In the `Development Guide`, I am in conduct of writing the `checker` part as well as draft the DG and draw the UML sequence model. -Of the team based tasks, I am in conduct of setting up the `github repo` and `github team`, release management and conduct meeting. -Basicly, all of us review our PR together, so we all share equal contribution in reviewing PRs. I have helped one of my teammates in setting up the ssh connection of github to make sure she can push the code to the origin. -For other contribution, I am in conduct of arrange the team meeting and gathering to help us stay togther in working out the problems we may meet. \ No newline at end of file +### Code contributed +[**Link To The Code**](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=yzhanglp&breakdown=true) +### New Features +- Add the `Checker` which collect and check the user's answer, return and record the accuracy and time cost +- Add the `explanation` to the overall framework, which shows the column caculation process of the problem +### Documentation +- `UserGuide:` In conduct of writing the introduction and review other parts +- `DeveloperGuide:` In conduct of draft framework, writing the `checker` part and draw the UML sequence model. +### Project Management +- In conduct of setting up the `github repo` and `github team` +- Release `v1.0` and `v2.0` and conduct weekly meeting. +### Community +- Review other teams' Code and give some recommandations. +- Accept others' suggestions and fix the problems they pointed out. +### Tool +- IntelliJ +- Vscode \ No newline at end of file diff --git a/recordList.txt b/recordList.txt deleted file mode 100644 index 7106120c98..0000000000 --- a/recordList.txt +++ /dev/null @@ -1,5 +0,0 @@ -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 diff --git a/src/main/java/seedu/duke/Calculator.java b/src/main/java/seedu/duke/Calculator.java index b386ff30df..c98422caec 100644 --- a/src/main/java/seedu/duke/Calculator.java +++ b/src/main/java/seedu/duke/Calculator.java @@ -7,13 +7,13 @@ import static java.lang.Character.isDigit; public class Calculator { - - private static List explanations = new ArrayList<>(); + + private static List explanations; public double calculate(StringBuilder sb) { Stack numStack = new Stack<>(); Stack opStack = new Stack<>(); - + explanations = new ArrayList<>(); ArrayList formula = toFormula(sb); ArrayList suffix = toSuffix(formula); for (Object object : suffix) { @@ -30,26 +30,26 @@ public double calculate(StringBuilder sb) { } assert numStack.size() == 1 : "wrong formula"; // round to 3 decimal places - Double result = Math.round(numStack.peek() * 1000.0) / 1000.0; - return result; + return Math.round(numStack.peek() * 1000.0) / 1000.0; } private static String getExplanation(double num1, double num2, String op, double answer) { String start = "The computation of the problem: " + - String.valueOf(num1) + " " + op + " " + - String.valueOf(num2) + " = " + - String.valueOf(answer) + "\n\n"; + num1 + " " + op + " " + + num2 + " = " + + answer + "\n\n"; List explanation = new ArrayList<>(); StringBuilder builder = new StringBuilder(); - String alignedProblem = ""; + String alignedProblem; if (op.equals("/")) { alignedProblem = "The division of " + num1 + " and " + num2 + " is " + answer + "\n"; } else { String firstString = String.valueOf(num1); String secondString = String.valueOf(num2); - String firstIntergerPart = firstString.split("\\.")[0]; - String secondIntergerPart = secondString.split("\\.")[0]; - if (firstIntergerPart.length() < secondIntergerPart.length()) { + String firstIntegerPart = firstString.split("\\.")[0]; + String secondIntegerPart = secondString.split("\\.")[0]; + // Put the longer number in the first place + if (firstIntegerPart.length() < secondIntegerPart.length()) { String temp = firstString; firstString = secondString; secondString = temp; @@ -189,14 +189,10 @@ private static ArrayList toFormula(StringBuilder sb) { return formula; } - public List getExplanations() { - return explanations; - } - public String getExplanationsString() { StringBuilder builder = new StringBuilder(); - for (String explanation : explanations) { - builder.append(explanation); + for (int i = 0; i < explanations.size(); i++) { + builder.append(i + 1).append(". ").append(explanations.get(i)); } return builder.toString(); } diff --git a/src/main/java/seedu/duke/Checker.java b/src/main/java/seedu/duke/Checker.java index 9d5fdc63d8..631b48778e 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 : "Input null test!"; + assert test != null : "You must intialize the checker with a test!"; this.userAnswer = new String[test.getNumber()]; this.test = test; this.isCorrect = new Boolean[test.getNumber()]; @@ -25,6 +25,7 @@ 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()); @@ -37,13 +38,15 @@ public static void showExplanation(Problem problem) { Boolean checkCorrectness(Problem problem, double answer) { - return Math.abs(problem.getAnswer() - answer) < 0.01; + if(Math.abs(problem.getAnswer() - answer) < 0.01) { + return true; + } + return false; } void getUserAnswer() { long startTime = System.currentTimeMillis(); - ui.print("Press Enter to start answering the questions, " + - "you can type \"exit\" to quit the test when answering the question..."); + ui.startAnswerTest(); String userInput = ui.readCommand(); for (int i = 0; i < test.getNumber(); i++) { @@ -54,7 +57,7 @@ void getUserAnswer() { double answer = Double.NEGATIVE_INFINITY; boolean isValid = false; if (userInput.equals("exit")) { - ui.print("Exit the test! All the test not finished will be marked as wrong!"); + ui.exitTest(); break; } while (!isValid) { @@ -87,7 +90,8 @@ void getUserAnswer() { this.time = (endTime - startTime) / 1000; for (int i = 0; i < test.getNumber(); i++) { if (isCorrect[i] = false) { - wrongProblem.add(test.getProblem().get(i)); + Problem problem = test.getProblem().get(i); + wrongProblem.add(problem); wrongAnswer.add(userAnswer[i]); } } diff --git a/src/main/java/seedu/duke/DIYProblemSet.java b/src/main/java/seedu/duke/DIYProblemSet.java index 3dad5075ed..4379f273ac 100644 --- a/src/main/java/seedu/duke/DIYProblemSet.java +++ b/src/main/java/seedu/duke/DIYProblemSet.java @@ -34,9 +34,9 @@ public void addDIYProblemSet(Ui ui) { correctAnswer = scanner.nextLine(); } } - - - Problem problem = new Problem(description, answer, explanations); + ui.print("Input the explanations of the problem (e.g. 1+2*3=7): "); + explanations = scanner.nextLine(); + Problem problem = new Problem(description,answer,explanations); problemSet.add(problem); ui.print("Have you finished adding problems? y/n: "); quit = scanner.nextLine(); @@ -50,6 +50,7 @@ public void addDIYProblemSet(Ui ui) { ui.print("Record successfully saved!"); record.print(true); Ui.showLine(); + scanner.close(); } diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index 22c8d4c76a..5ee70d0dcf 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -71,21 +71,22 @@ public static void parseRecord(String description, Ui ui) { public static void solveProbSet(Test test, Ui ui, boolean retry, int id) { Checker checker = new Checker(test); checker.getUserAnswer(); - String accRate = String.format("%.2f", checker.getAccuracy() * 100); - ui.print("Acc: " + accRate + "%"); - ui.print("Spend Time: " + checker.getTime() + "s"); + // Use the % format to print acc + ui.showTestResult(checker.getAccuracy(), checker.getTime()); + + + // Show the wrong answer List wrongAnswer = checker.getWrongAnswer(); List wrongProblem = checker.getWrongProblem(); - ui.print("The following " + wrongProblem.size() + " answers you gave are wrong: \n"); + ui.showWrongAnswer(wrongProblem.size()); for (int i = 0; i < wrongProblem.size(); i++) { Problem problem = wrongProblem.get(i); ui.print("The " + (i + 1) + "th wrong answer of you: "); ui.print("Your answer: " + problem.getDescription() + " = " + wrongAnswer.get(i)); ui.print("Correct Answer: " + problem.solved()); - // need further implementation for 3 more operators - ui.print("If you want to see the explanation, type exp or explanation, else just type enter, " + - "type exit to stop showing the answer"); + ui.showExplanation(); + String userInput = ui.readCommand(); if (userInput.equals("exit")) { break; @@ -93,6 +94,8 @@ public static void solveProbSet(Test test, Ui ui, boolean retry, int id) { if (userInput.equals("exp") || userInput.equals("explanation")) { Checker.showExplanation(problem); } + + ui.showExplanationEnd(); } // Storage write to file diff --git a/src/main/java/seedu/duke/ProblemGenerator.java b/src/main/java/seedu/duke/ProblemGenerator.java index a630fe7bd9..4b727d497b 100644 --- a/src/main/java/seedu/duke/ProblemGenerator.java +++ b/src/main/java/seedu/duke/ProblemGenerator.java @@ -171,6 +171,10 @@ private Test generate(HashMap parameter) { 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++) { diff --git a/src/main/java/seedu/duke/Ui.java b/src/main/java/seedu/duke/Ui.java index 9eb5910028..c67158daed 100644 --- a/src/main/java/seedu/duke/Ui.java +++ b/src/main/java/seedu/duke/Ui.java @@ -49,8 +49,36 @@ public class Ui { private static final String DIY_COMMAND = "Add user defined problem sets in to the problem database: \t" + "DIY\n"; + private static final String EXIT_COMMAND = "Exit program: exit\n"; + private static final String EXPLANATION_START = + "\nExplanation Instruction: \n" + + "1.To view the explanation of a problem, type 'explanation' or 'exp'.\n" + + "2. The explanation of the problem will be shown step by step with the formulation of column caculation.\n" + + "3. If you want to exit the explanation, type 'exit'."; + + private static final String EXPLANATION_END = + "Explanation End."; + + private static final String WRONG_ANSWER = + "We evaluate the answer accurate in 2 decimal places.\n"+ + "You may check the answer as well as the explanation.\n"+ + "If you do not want to see the explanation, type 'exit'."; + + private static final String START_ANSWER_TEST = + "START ANSWERING TEST INSTRUCTION:\n" + + "1.Press Enter to start answering the questions.\n" + + "2.You can type \"exit\" to quit the test when answering the question.\n"+ + "3.You may round the answer to 2 decimal places for complex answers."; + + private static final String EXIT_TEST = + "Exit the test! All the test not finished will be marked as wrong! No explanation for them!"; + + private static final String TEST_FINISH = + "TEST FINISHED! \n"+ + "Here is your test result: "; + private final String name; private final Scanner scanner = new Scanner(System.in); @@ -157,6 +185,50 @@ static void missingMessage(String parameters) { System.out.println("Using default " + parameters + " instead!"); } + public void showExplanation() { + System.out.println(EXPLANATION_START); + showLine(); + } + + public void showExplanationEnd() { + System.out.println(EXPLANATION_END); + showLine(); + } + + public void showWrongAnswer(int i) { + System.out.println("You have " + i + " wrong answers."); + System.out.println(WRONG_ANSWER); + System.out.println("The following " + i + " answers you gave are wrong: "); + showLine(); + } + + public void startAnswerTest() { + showLine(); + System.out.println(START_ANSWER_TEST); + showLine(); + } + + public void exitTest() { + System.out.println(EXIT_TEST); + showLine(); + } + + public void showTestResult(double acc, long time) { + System.out.println(TEST_FINISH); + String accRate = String.format("%.2f", acc * 100); + System.out.println("Accuracy: " + accRate + "%"); + System.out.println("Time Spend: " + time + "s"); + + if(acc>=90) { + System.out.println("Well Done! You have a good performance!"); + } else if(acc>=50) { + System.out.println("Good Job! Keep going!"); + } else { + System.out.println("You may need more practice!"); + } + showLine(); + } + public void exit() { System.out.println("Bye. Hope to see you again soon!"); showLine(); diff --git a/src/test/java/seedu/duke/CheckerTest.java b/src/test/java/seedu/duke/CheckerTest.java index 0cdfa1087f..04d8cb3792 100644 --- a/src/test/java/seedu/duke/CheckerTest.java +++ b/src/test/java/seedu/duke/CheckerTest.java @@ -4,7 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class CheckerTest { - private Checker checker; @org.junit.jupiter.api.Test public void sampleTest() {