From 0f7bb8f4ba0b7099b145517d28374cf7291ce2bd Mon Sep 17 00:00:00 2001 From: LIN Siyan Date: Fri, 12 Apr 2024 06:02:40 +0800 Subject: [PATCH] Add class DIYProblemSet and ProblemSetType, modify Storage, Record, Ui and Test to show the ProblemSetType, add PPP draft and modify the UG and DG. --- docs/DeveloperGuide.md | 53 +++++++++++++++++++- docs/UserGuide.md | 19 ++++--- docs/team/celineyaa.md | 35 +++++++++++++ src/main/java/seedu/duke/DIYProblemSet.java | 46 +++++++++++++++++ src/main/java/seedu/duke/Parser.java | 7 ++- src/main/java/seedu/duke/ProblemSetType.java | 16 ++++++ src/main/java/seedu/duke/Record.java | 17 +++++-- src/main/java/seedu/duke/Storage.java | 10 ++-- src/main/java/seedu/duke/Test.java | 8 ++- src/main/java/seedu/duke/Ui.java | 9 +++- src/test/java/seedu/duke/StorageTest.java | 14 +++--- 11 files changed, 208 insertions(+), 26 deletions(-) create mode 100644 docs/team/celineyaa.md create mode 100644 src/main/java/seedu/duke/DIYProblemSet.java create mode 100644 src/main/java/seedu/duke/ProblemSetType.java diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f0a7f2c016..2e89e1d555 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -104,7 +104,7 @@ Each `Record` object stores an ArrayList of `Problem` objects for storing specif When a problem set solving is saved to a record **for the first time**, the corresponding `Record` object will create a unique ID for the problem set using Java's built-in `hashCode` method. When loading this record in the future and re-saving the data, the same ID will be used and no new IDs will be generated. This is achieved by using two different constructors for these two different situations. **Code Snippet** -```java +``` // the two different constructors public Record(LocalDateTime dateTime, double speed, double accuracy, ArrayList probSet) { setSpeed(speed); @@ -121,7 +121,7 @@ public Record(LocalDateTime dateTime, double speed, double accuracy, ArrayList

problemSet; + + public DIYProblemSet() { + // Constructor logic + } + + public void addDIYProblemSet(Ui ui) { + // Method logic + } + } +``` + ## Class Variables + + problemSet: An ArrayList of type Problem to store the user-defined problems. + + ## Class Methods + +``` + public DIYProblemSet() +``` + The constructor initializes the problemSet as a new ArrayList of Problem objects. + +``` + public void addDIYProblemSet(Ui ui) +``` + This method allows users to input their DIY problem set. It prompts for the problem description and correct answer, validates the input, and adds the problem to the problemSet. Once the user finishes adding problems, it creates a new Record object with the current timestamp, total correct answers set to 0, total time taken set to 0, the problemSet, and the problem set type as USER_DIY. It then saves the record using the Storage.addRecord() method and displays a success message along with the details of the saved problem set. + + ## Method Flow +1. Create a new Scanner object to read user input. +2. Prompt the user to input their DIY problem set. +3. Inside a loop that continues until the user indicates they have finished adding problems: + - Prompt the user to input the problem description. + - Prompt the user to input the correct answer for the problem. + - Validate the input by attempting to parse the correct answer as a double. If it fails, display an error message. + - Create a new Problem object with the description and parsed answer, and add it to the problemSet. + - Prompt the user to indicate if they have finished adding problems (y for yes, n for no). + - Validate the input to ensure it is either y or n. If it is invalid, display an error message and prompt again. +4. Create a new Record object with the current timestamp, total correct answers set to 0, total time taken set to 0, the problemSet, and the problem set type as USER_DIY. +5. Save the record using the Storage.addRecord() method. +6. Display a success message indicating that the DIY problem set has been successfully saved. +7. Print the details of the saved problem set using the record.print(true) method. +8. Display a new line for formatting purposes. + ### Testcase Component # Proposed Implementation diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 344ec63d61..865868289f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -78,6 +78,9 @@ type the answer in the terminal and press ENTER/RETURN After finishing all the problem sets, the program will automate judged the correctness and output the accuracy and speed. +### DIY: `DIY` +Add user DIY problem sets into our problem set datasets. The DIY problem set can also be saved and retried. + ### Exit: `exit` User can use this to exit the program. @@ -92,18 +95,20 @@ Here are some example commands you can try: 2. Pressing `Enter/Return`: Submits your answer to a problem. 3. `exit`: Exits the program. 4. `records`: Displays your past problem-solving sessions, including the date you finished the set, your speed, accuracy, and the details of the problems. +5. `DIY`: Add user DIY problem sets into our problem set datasets. The DIY problem set can also be saved and retried. Remember, practice makes perfect. Happy learning with **MathGenius**! ### Command summary: -| Command | Description | Format | Example | -|---------|-------------|--------|---------| -| `help` | Show the message about the command you can use and the standard input format | `help COMMAND_NAME` | `help generate` | -| `gen / generate` | Generate the problem based on series of parameters | `generate -t OPERATOR -n NUMBER_OF_PROBLEMS -d MAXIMUM_DIGITS` | `generate -t + -n 1 -d 1` | -| `records` | View the records of your past problem solving sessions | `records -sortByDate -sortBySpeed -sortByAccuracy -sortByProblemID -showProblemDetails` | `records -d -s -a -p -details` | -| `ENTER/RETURN` | Submit the answer in the terminal | NA | NA | -| `exit` | Exit the program | `exit` | `exit` | +| Command | Description | Format | Example | +|------------------|-------------|-----------------------------------------------------------------------------------------|--------------------------------| +| `help` | Show the message about the command you can use and the standard input format | `help COMMAND_NAME` | `help generate` | +| `gen / generate` | Generate the problem based on series of parameters | `generate -t OPERATOR -n NUMBER_OF_PROBLEMS -d MAXIMUM_DIGITS` | `generate -t + -n 1 -d 1` | +| `records` | View the records of your past problem solving sessions | `records -sortByDate -sortBySpeed -sortByAccuracy -sortByProblemID -showProblemDetails` | `records -d -s -a -p -details` | +| `ENTER/RETURN` | Submit the answer in the terminal | NA | NA | +| `DIY` | Add user DIY problem sets into our problem set datasets. | `DIY` | `DIY` | +| `exit` | Exit the program | `exit`| `exit` | ## Interaction Guide diff --git a/docs/team/celineyaa.md b/docs/team/celineyaa.md new file mode 100644 index 0000000000..12a9157579 --- /dev/null +++ b/docs/team/celineyaa.md @@ -0,0 +1,35 @@ +# Yuhao ZHANG + +## 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=celineyaa&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) +In the project `MathGenius`, I am in conduct of implement the `DIYProblemSet` part and test cases part. For the `DIYProblemSet` which is to add user-DIY problem sets into our problem sets database. And for the testcases part, they are used to test the functionality of classes. +In the `UserGuide`,I am in conduct of writing the corresponding parts of the guidance. +In the `Development Guide`, I am in conduct of writing the `testcases` part, `DIYProblemSet`part and `Instructions for manual testing`part. +Of the team base tasks, I attend weekly meeting most of the time and do the allocated tasks as soon as possible. +I also help to check the correctness of others part and provide advices on the improvements. + +## Project management: +Managed release `v1.0` on GitHub + +## Challenges: +During the refinement process, I faced a few challenges, including: +- Dealing with unexpected errors and exceptions: Throughout the refinement process, unexpected errors and exceptions were encountered. These issues required thorough debugging and error handling to identify the root causes and implement appropriate solutions to prevent or handle such errors gracefully. +- Optimizing performance and scalability: Another challenge was optimizing the software's performance and ensuring scalability to handle increasing user loads. This involved identifying and resolving bottlenecks, implementing efficient algorithms, and conducting performance testing to ensure the system could handle large-scale usage. +- Collaborating with team members and managing project coordination: If the project involved a team, effective collaboration and project coordination were essential challenges. This included communicating and coordinating tasks with team members, resolving conflicts or differences in opinions, and ensuring everyone was aligned with the project goals and timeline. + +## Community: +- Contributions to test code and text-ui-test for Gradle. +- Promoting coding style consistency. +- Sharing knowledge and expertise. + +## Next Steps: +- Organize usability testing sessions with users to gather feedback on the existing documentation. This will help identify any areas that might be confusing or require further clarification. Incorporate the feedback received into the documentation refinement process. +- Analyze common user issues and questions that have been raised during the project's development and deployment. Use this information to expand the troubleshooting section of the User Guide, providing step-by-step solutions to common problems. Additionally, create a comprehensive FAQs section to address frequently asked questions and provide quick answers to users. +- Enhance the documentation by including relevant diagrams, flowcharts, and visuals where appropriate. These visual aids can help users and developers better understand complex concepts, system architecture, and workflows. + +## Tools: + - IntelliJ + diff --git a/src/main/java/seedu/duke/DIYProblemSet.java b/src/main/java/seedu/duke/DIYProblemSet.java new file mode 100644 index 0000000000..7642c25e30 --- /dev/null +++ b/src/main/java/seedu/duke/DIYProblemSet.java @@ -0,0 +1,46 @@ +package seedu.duke; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Scanner; + +public class DIYProblemSet { + ArrayList problemSet; + public DIYProblemSet() { + problemSet = new ArrayList<>(); + } + public void addDIYProblemSet(Ui ui) { + Scanner scanner = new Scanner(System.in); + ui.print("Please input your DIY problemSet: "); + String description; + String correctAnswer; + double answer = 0.0; + String quit = ""; + while (!quit.equals("y")) { + ui.print("input the description of the problem (e.g. 1+2*3): "); + description = scanner.nextLine(); + ui.print("input the correct answer of the problem (e.g. 7): "); + correctAnswer = scanner.nextLine(); + try { + answer = Double.parseDouble(correctAnswer); + } catch (NumberFormatException e) { + ui.print("Invalid answer! Please input a number."); + } + Problem problem = new Problem(description,answer); + problemSet.add(problem); + ui.print("Do you finish adding problems? y/n: "); + quit = scanner.nextLine(); + while (!quit.equals("y") && !quit.equals("n")) { + ui.print("input is invalid! Please input 'y' or 'n': "); + quit = scanner.nextLine(); + } + } + Record record = new Record(LocalDateTime.now(),0.0, 0.0,problemSet,ProblemSetType.USER_DIY.getValue()); + Storage.addRecord(record); + ui.print("\nSuccessfully save the DIY problem set!"); + record.print(true); + ui.print("\n"); + } + + +} diff --git a/src/main/java/seedu/duke/Parser.java b/src/main/java/seedu/duke/Parser.java index d042bc8b4b..e73fc0533c 100644 --- a/src/main/java/seedu/duke/Parser.java +++ b/src/main/java/seedu/duke/Parser.java @@ -91,9 +91,9 @@ public static void solveProbSet(Test test, Ui ui, boolean retry, int id) { // Storage write to file double speed = (double) test.getNumber() / checker.getTime() * 60; if (retry) { - Storage.addRecord(new Record(LocalDateTime.now(), speed, checker.getAccuracy(), test.getProblem(), id)); + Storage.addRecord(new Record(LocalDateTime.now(), speed, checker.getAccuracy(), test.getProblem(), id, test.getProblemSetType())); } else { - Storage.addRecord(new Record(LocalDateTime.now(), speed, checker.getAccuracy(), test.getProblem())); + Storage.addRecord(new Record(LocalDateTime.now(), speed, checker.getAccuracy(), test.getProblem(), test.getProblemSetType())); } Storage.writeFile(); } @@ -132,6 +132,9 @@ public static void parse(String command, Ui ui) { case "retry": parseRetry(description, ui); break; + case "DIY": + DIYProblemSet DIY = new DIYProblemSet(); + DIY.addDIYProblemSet(ui); case "help": ui.help(description); break; diff --git a/src/main/java/seedu/duke/ProblemSetType.java b/src/main/java/seedu/duke/ProblemSetType.java new file mode 100644 index 0000000000..dd6e2067c1 --- /dev/null +++ b/src/main/java/seedu/duke/ProblemSetType.java @@ -0,0 +1,16 @@ +package seedu.duke; + +public enum ProblemSetType { + USER_DIY("user-DIY"), + AUTO_GENERATED("auto-generated"); + + private String value; + + private ProblemSetType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/seedu/duke/Record.java b/src/main/java/seedu/duke/Record.java index c6c4d6a9dc..5a4c3e6dbb 100644 --- a/src/main/java/seedu/duke/Record.java +++ b/src/main/java/seedu/duke/Record.java @@ -16,23 +16,28 @@ public class Record { private final ArrayList probSet = new ArrayList<>(); private int psIndex; + private String problemSetType; - public Record(LocalDateTime dateTime, double speed, double accuracy, ArrayList probSet) { + public Record(LocalDateTime dateTime, double speed, double accuracy, ArrayList probSet, String problemSetType) { setSpeed(speed); setAccuracy(accuracy); setDateTime(dateTime); setProbSet(probSet); + setProblemSetType(problemSetType); psIndex = probSet.hashCode(); + } - public Record(LocalDateTime dateTime, double speed, double accuracy, ArrayList probSet, int psIndex) { + public Record(LocalDateTime dateTime, double speed, double accuracy, ArrayList probSet, int psIndex, String problemSetType) { setSpeed(speed); setAccuracy(accuracy); setDateTime(dateTime); setProbSet(probSet); setPsIndex(psIndex); + setProblemSetType(problemSetType); } + public void print(boolean showProbDetails) { // ui.printRecords(showProbDetails, this); @@ -45,6 +50,7 @@ public void print(boolean showProbDetails) { } System.out.println("Speed: " + getSpeed() + " problems per minute"); System.out.println("Accuracy: " + getAccuracy() * 100 + "%"); + System.out.println("Problem Set type: " + getProblemSetType()); } public String writeLine() { @@ -55,7 +61,7 @@ public String writeLine() { } return getDateTime().format(formatter) + " " + getSpeed() + " " + - getAccuracy() + " " + getPsIndex() + " " + probStr; + getAccuracy() + " " + getPsIndex() + " " + getProblemSetType() + " " + probStr; } public int getPsIndex() { @@ -97,4 +103,9 @@ public LocalDateTime getDateTime() { public void setDateTime(LocalDateTime dateTime) { this.dateTime = dateTime; } + + public void setProblemSetType(String problemSetType) { this.problemSetType = problemSetType; } + + public String getProblemSetType() { return problemSetType; } + } diff --git a/src/main/java/seedu/duke/Storage.java b/src/main/java/seedu/duke/Storage.java index c43627d2d8..74b33309ef 100644 --- a/src/main/java/seedu/duke/Storage.java +++ b/src/main/java/seedu/duke/Storage.java @@ -35,7 +35,7 @@ public static void clearRecords() { public static Test problemSetByID(int id) { for (Record record : records) { if (record.getPsIndex() == id) { - return new Test(record.getProbSet()); + return new Test(record.getProbSet(),record.getProblemSetType()); } } return null; @@ -76,7 +76,7 @@ public static ArrayList sortRecords(int dateSortOp, int spdSortOp, int a * @throws Exception exception is thrown whenever the input format is corrupt. */ public static void processLine(String line) throws Exception { - int minimumLength = 4; + int minimumLength = 5; String[] words = line.split(" "); @@ -90,6 +90,8 @@ public static void processLine(String line) throws Exception { int psIndex = Integer.parseInt(words[4]); + String problemSetType = words[5]; + ArrayList probSet = new ArrayList<>(); for (int i = minimumLength + 1; i < words.length; i++) { @@ -97,7 +99,9 @@ public static void processLine(String line) throws Exception { probSet.add(new Problem(term[0], Double.parseDouble(term[1]))); } - Record record = new Record(dateTime, speed, accuracy, probSet, psIndex); + + + Record record = new Record(dateTime, speed, accuracy, probSet, psIndex,problemSetType); addRecord(record); } diff --git a/src/main/java/seedu/duke/Test.java b/src/main/java/seedu/duke/Test.java index 2ca5a0176c..af1aba30a4 100644 --- a/src/main/java/seedu/duke/Test.java +++ b/src/main/java/seedu/duke/Test.java @@ -10,18 +10,22 @@ public class Test { int length; ArrayList problemList = new ArrayList<>(); + String problemSetType; public Test(String operators, int maxDigits, int number, int length) { this.operators = operators; this.maxDigits = maxDigits; this.number = number; + this.length = length; + this.problemSetType = ProblemSetType.AUTO_GENERATED.getValue(); } - public Test(ArrayList problemList) { + public Test(ArrayList problemList, String problemSetType) { this.operators = ""; this.maxDigits = 0; this.number = problemList.size(); this.problemList = new ArrayList<>(problemList); + this.problemSetType = problemSetType; } public void addToTest(Problem p) { @@ -36,4 +40,6 @@ public ArrayList getProblem() { return problemList; } + public String getProblemSetType() { return problemSetType; } + } diff --git a/src/main/java/seedu/duke/Ui.java b/src/main/java/seedu/duke/Ui.java index 7d16b80ad7..07feced590 100644 --- a/src/main/java/seedu/duke/Ui.java +++ b/src/main/java/seedu/duke/Ui.java @@ -33,7 +33,8 @@ public class Ui { "1. 'generate' or 'gen': Generate a problem set based on a series of parameters.\n" + "2. 'records': View the records of your past problem solving sessions.\n" + "3. 'retry': Retry a problem set you have solved before.\n" + - "4. 'exit': Exit the program.\n" + + "4. 'DIY': add user-DIY problem set to the problem set database.\n" + + "5. 'exit': Exit the program.\n" + "For example, 'help generate' will show you how to use the generate command."; private static final String RECORDS_COMMAND = "View past records(in-brackets parameters are optional): \t" + "records [-d] [-s] [-a] [-p] [-details]\n" + @@ -45,8 +46,12 @@ public class Ui { private static final String RETRY_COMMAND = "Retry a problem set you have solved before in the past: \t" + "retry PROBLEM_SET_ID\n" + "PROBLEM_SET_ID is an integer, and can be found by using the 'records' command.\n"; + + 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 final String name; private final Scanner scanner = new Scanner(System.in); @@ -104,6 +109,8 @@ public void help(String helpType) { case "exit": System.out.println(EXIT_COMMAND); break; + case "DIY": + System.out.println(DIY_COMMAND); default:// by default, user asks Help Instruction System.out.println(HELP_COMMAND); break; diff --git a/src/test/java/seedu/duke/StorageTest.java b/src/test/java/seedu/duke/StorageTest.java index 96bddabd8c..0a48c19a14 100644 --- a/src/test/java/seedu/duke/StorageTest.java +++ b/src/test/java/seedu/duke/StorageTest.java @@ -10,9 +10,9 @@ public class StorageTest { public static void testSortRecords() { - Record record1 = new Record(LocalDateTime.now().minusDays(2), 5.0, 0.8, new ArrayList<>()); - Record record2 = new Record(LocalDateTime.now().minusDays(1), 6.0, 0.7, new ArrayList<>()); - Record record3 = new Record(LocalDateTime.now(), 7.0, 0.9, new ArrayList<>()); + Record record1 = new Record(LocalDateTime.now().minusDays(2), 5.0, 0.8, new ArrayList<>(), "user-DIY"); + Record record2 = new Record(LocalDateTime.now().minusDays(1), 6.0, 0.7, new ArrayList<>(), "auto-generated"); + Record record3 = new Record(LocalDateTime.now(), 7.0, 0.9, new ArrayList<>(), "auto-generated"); Storage.addRecord(record1); Storage.addRecord(record2); Storage.addRecord(record3); @@ -60,15 +60,15 @@ public static void testSortRecords() { } public static void testAddRecord() { - Record record = new Record(LocalDateTime.now(), 5.0, 0.8, new ArrayList<>()); + Record record = new Record(LocalDateTime.now(), 5.0, 0.8, new ArrayList<>(),"auto-generated"); Storage.addRecord(record); assertEquals(1, Storage.getRecords().size()); assertEquals(record, Storage.getRecords().get(0)); } public static void testClearRecords() { - Record record1 = new Record(LocalDateTime.now(), 5.0, 0.8, new ArrayList<>()); - Record record2 = new Record(LocalDateTime.now(), 6.0, 0.7, new ArrayList<>()); + Record record1 = new Record(LocalDateTime.now(), 5.0, 0.8, new ArrayList<>(), "auto-generated"); + Record record2 = new Record(LocalDateTime.now(), 6.0, 0.7, new ArrayList<>(), "user-DIY"); Storage.addRecord(record1); Storage.addRecord(record2); assertEquals(2, Storage.getRecords().size()); @@ -77,7 +77,7 @@ public static void testClearRecords() { } public static void testProcessLine() { - String line = "2024-04-04 10:30:00 5.0 0.8 1234 problem1,1.0 problem2,2.0"; + String line = "2024-04-04 10:30:00 5.0 0.8 1234 auto-generated problem1,1.0 problem2,2.0"; try { Storage.processLine(line); assertEquals(1, Storage.getRecords().size());