notes)`: prints out all the notes sorted based on the
+priority (HIGH, MEDIUM, LOW) of the note items in a list format.
+
+### NotePriority class:
+The `NotePriority` class is utilised to set the priority level (LOW, MEDIUM, HIGH)
+of the notes stored in the Notes List by users.
+
+### Help
+The Help feature allows users to view possible options by calling `Help.` which reads the content stored in the HelpManual.txt.
+
+The feature implemented involves reading the content from HelpManual.txt file and logging the result of read operation using the Java Logging API.
+
+#### HelpManual text:
+`HelpManual.txt` is a text file that contains the help manual for BadMaths. It is located in the `src/main/resources` directory of the project.
+The purpose of this file is to provide users with helpful instructions on how to operate BadMaths.
+
+#### HelpManual class:
+Step 1. Define the HelpManual class: The HelpManual class is defined as a public class with two static fields: filePath and logFilePath.
+These fields contain the file path of the HelpManual.txt file and the name of the log file, respectively.
+
+Step 2. Setting up the Logger: The Logger is set up in the HelpManual class using the Java Logging API.
+The `setUpLogger()` method resets the LogManager, sets the logger's level to ALL, and creates a log file if it does not already exist.
+This method is called before the `readHelpManual()` method to ensure that the logger is properly configured.
+
+Step 3. Reading the file:
+The `readHelpManual()` method is implemented to read the content from the HelpManual.txt file.
+It first calls the setUpLogger() method to configure the logger. Then it obtains an InputStream object that reads the content from the
+file using the `getResourceAsStream()` method. Before reading the file, the `readHelpManual()` method asserts that the input stream is not null to ensure that the file exists and is readable.
+The file is then read line by line using a BufferedReader object, and each line is appended to a StringBuilder object. Otherwise,
+the `getResourceAsStream()` method will return a null value, and an `AssertionError` will be thrown.
+
+Step 4. Logging the result: After reading the file, the `readHelpManual()` method closes the BufferedReader and InputStream
+objects and logs the success or failure of the read operation using the logger. If the read operation is successful, a message
+is logged to the console and log file indicating that the HelpManual file was successfully read. If an exception occurs during
+the read operation, an error message is logged to the console and log file.
+
+### Graph
+The Graph feature allows users to analyse basic Trigonometry signals by calling `startGraphAnalysis()` which
+creates a new instance of `TrigoGraphAnalyser` named `analyser`.
+
+Below is an example usage scenario and how the `Graph` feature behaves at each step.
+
+When user enters an input:
+```
+Graph. 2*sin(2*x+5)-1
+```
+#### Parser class, Command class:
+Step 1. Parser class will split the input into `Graph.` and `2*sin(2*x+5)-1`, which are `command` and `toDo` respectively.
+The command class creates a new instance of `TrigoGraph` and pass in `toDo` as a parameter for the constructor. It
+then executes `trigoGraph.startGraphAnalysis()`based on `command` using switch-case statements.
+
+#### TrigoGraph class:
+
+Sequence Diagram for TrigoGraph class
+
+
+
+
+
+
+
+
+Class Diagram for TrigoGraph class
+
+
+
+
+
+
+
+Step 2. Constructor for the TrigoGraph class takes in `2*sin(2*x+5)-1` and assigns it to `trigoEqn` of type String. When `startGraphAnalysis()`
+is called from the command class, a new instance of `TrigoGraphAnalyser` called `analyser` is created in TrigoGraph, which accepts `trigoEqn`
+as the parameter.
+
+Step 3. When `analyser.canStartAnalyser()` is true, it will print out the amplitude, frequency, phase and vertical shift
+to the user using the Ui class. Each of the method calls to the Ui class requires an input of type double which can
+be achieved by calling `analyser.getAmplitude()`, `analyser.getFreq()` and so on.
+
+#### TrigoGraphAnalyser class:
+Step 4. In the `canStartAnalyser()` method, the trigo equation is split into various parts, and there
+is a method call to create `setUpLogger()` to log exceptions when user enters
+invalid trigo equation. `canStartAnalyser()` returns false if an exception is reached, else it returns true.
+
+Step 5. `canStartAnalyser()` calls `splitAmplitudeFromTrigoEqn()`. This method will split
+the input into `2` and `sin(2*x+5)-1` using `*` as the regex.
+
+Step 6. 2 tests are ran within `splitAmplitudeFromTrigoEqn()` to check for negative amplitude and multiple asterisk.
+In this case, both checks will return false.
+
+Step 7. The separated String is passed into `String[] amplitudeAndEqn`. The string is then passed into `findAmplitude`
+to determine the amplitude. In `findAmplitude(eqn)`, `isAmplitudeEqualsToOne(eqn[0])` will check if the input string
+starts with `cos`, `sin` or `tan`, where `eqn[0]` is `2` and `eqn[1]` is `sin(2*x+5)-1`.
+If this is true, 1.0 will be assigned to `amplitude`. Else, string `2` will be converted to double `2.0` and assigned to
+`amplitude`.
+
+Step 8. After finding `amplitude`, `canStartAnalyser()` calls `splitTrigoAndVerticalShift(amplitudeAndEqn[1])`, where
+`amplitudeAndEqn[1]` is `sin(2*x+5)-1`. `splitTrigoAndVerticalShift` splits `sin(2*x+5)-1` into `sin(2*x+5` and `-1`
+based on `)` and returns the separated string to `trigoAndVerticalShift`.
+
+Step 9. `canStartAnalyser()` calls `findVerticalShift()` which takes in `sin(2*x+5` and `-1` as a string [] parameter.
+In `findVerticalShift()`, method call to `isVerticalShiftZero(-1)` is false and thus,
+`-1` is converted to double `-1.0` and assigned to `vertricalShift`.
+
+Step 10. In `canStartAnalyser()`, string `trigo` is assigned `sin(2*x+5`.
+
+Step 11. `canStartAnalyser()` calls `splitTrigoIntoPhasors()` and takes in `trigo` as the parameter. In `splitTrigoIntoPhasors()`,
+`startPosOfPhase` is 4 while `endPosOfPhase` is 9. A new String variable `phase` is assigned the substring of trigo from
+4 to 9, resulting in `2*x+5`. `splitPhasorsIntoFreq()` is called and it accepts string `2*x+5` as input.
+
+Step 12. In `splitPhasorsIntoFreq()`, `findFreqForPlus()` is called which takes in string `2*x+5` as input.
+
+Step 13. In `findFreqForPlus()`, `2*x+5` is split into `2*x` and `5` using the split function with `+` as the regex.
+`findPhase()` which accepts `5` and a boolean `false` as parameters, and `findFreq()` which accepts `2*x` and a boolean `false` are called.
+
+Step 14. In `findPhase()`, `phase` is assigned the double of `5` and in `findFreq()`, `2*x` is substring into `2` and converted
+to double `2.0`. `Freq` is assigned the double value of `2.0 / (2 * Math.PI)`.
+
+Step 15. Finally, `canStartAnalyser()` reaches the end and returns true.
+
+#### TrigoGraphVisualiser class:
+Step 16. The `TrigoGraphVisualiser` extends JPanel and overrides the `paintComponent()` method in JComponent.
+
+Step 17. A new instance of `TrigoGraphVisualiser` is created in `startGraphAnalysis` to assign corresponding values to the amplitude, phase, frequency,
+vertical shift, and the trigonometric function in `TrigoGraphVisualiser`. Next, `startVisualiser()` is called to create the frame
+for the graph.
+
+
+Step 18. The frame is set half of the screen size using `setSize()` and `getScreenSize()`.
+
+Step 19. When the frame is created, `paintComponent` will be called. It sets up the scale factors which will scale the values
+generated by the trigo function to that of the frame. It the sets up the x and y axis using `g.drawLine()`.
+
+Step 20. Using the switch-case statements. `drawSinCurve()` will be executed and amplitudes will be labelled on the axis.
+The for loop will run from `xMin` to `xMax`, which are the negative frequency and positive frequency for one period respectively.
+After getting the y value from the output of the sin equation, both *x* and *y* are scaled to *xPixel* and *yPixel* respectively. A horizontal line is drawn at every pixel, which
+eventually forms the sine graph.
+
+### Matrix
+
+The Matrix feature supports various basic matrix calculations below:
+* Matrix multiplication
+* Matrix element wise product
+* Matrix addition
+* Matrix subtraction
+
+With calling `calculator.run()`, BadMaths parses the user's input and conducts the given command.
+
+If you want to see the overall flow of the Matrix part, click the toggle button below:
+
+
+See the Class Diagram
+
+
+
+
+
+
+
+
+See the Sequence Diagram
+
+
+
+
+
+
+
+
+
+Below is an example usage scenario and how the `Matrix` feature behaves at each step.
+
+When user enters an input:
+```
+Matrix [1,2;3,4] .* [5,6;7,8]
+```
+
+#### Calculator class
+
+step 1. `run()` function in `Calculator.class` firstly get `toDo` as the argument which is `[1,2;3,4] .* [5,6;7,8]` in the above example.
+This `run()` function sequentially parses this string, executes the command and shows the result matrix to users.
+
+#### Parser class
+
+step 2. Firstly, `run()` function pass the `toDo` string to `parse()` function defined in `Parser.class`.
+This `parse()` function firstly identifies the type of the operator of this command with referring `toDo` string.
+And then, it divides the cases with this identified type with using `switch` statement.
+
+#### Execute class
+
+step 3. According to each case divided by operator types in the previous step,
+`parse()` function calls corresponding function defined in `Execute.class` for conducting calculation.
+In the case of the above example, `parse()` function calls `executeMul()` defined in `Execute.class` since the type of the
+operator is matrix multiplication. Finally, it passes the `toDo` string to `executeMul()` function as the argument.
+
+step4. `executeMul()` function firstly extracts two operands from `toDo` string. And pass these two operands to `executeTranspose()`
+in `Execute.class` respectively.
+
+step 5. In this `executeTranspose()` function, function checks whether there is transpose mark in the given operand, and parses this
+operand which is string type into `Tensor2D` type so that this operand could be internally calculated. In this parsing phase,
+`parseMatrix()` function defined in `Parser.class` is used. This function finally outputs this `Tensor2D` type operand to
+`executeMatrix()` function.
+
+step 6. Regarding these two operands with `Tensor2D` type, `executeMul` function calls `mul()` function defined in `calculate.class`.
+
+#### Calculate class
+
+step 7. `mul()` function defined in `Calculate.class` internally conducts matrix multiplication with nested for-loop
+and outputs the result which is `Tensor2D` type.
+
+step 8. This result is sequentially returned to `executeMul()`, `parse()` and `run()` function. Finally in the `run()` function,
+the result is printed in terminal.
+
+
+## Product Scope
+### Target user profile
+Mathematics students who are studying and practicing Mathematical topics on Matrices, Quadratic Equations
+or Sinusoidal Signals.
### Value proposition
-{Describe the value proposition: what problem does it solve?}
+Students can access mathematical tools like matrix calculator, quadratic equation solver, and trigonometry graph analyser
+quickly when studying. Concurrently, students are also able to make use of the Notes function in BadMaths
+to do note-taking and to keep track of their notes through the use of various Notes features in BadMaths.
+
+This integrated mathematical tool aims to help users solve their mathematical doubts or clarifications quickly which saves time, as they do not
+have to search for different tools online.
+
## User Stories
-|Version| As a ... | I want to ... | So that I can ...|
-|--------|----------|---------------|------------------|
-|v1.0|new user|see usage instructions|refer to them when I forget how to use the application|
-|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list|
+| Version | As a ... | I want to ... | So that I can ... |
+|---------|-----------------------------------------|------------------------------------------------------------|-----------------------------------------------------------------------------------------|
+| v1.0 | student studying Linear Algebra | be able to check my answers for Matrix multiplications | ensure that the method I am using for manual calculations is correct |
+| v1.0 | student overwhelmed by math information | be able to store custom notes | refer to them whenever I want to refresh my memory |
+| v1.0 | student studying Signals and Systems | be able to find the characteristics of trigo graphs easily | save time when doing my tutorials and not have to worry about the tedious calculations |
+| v2.0 | secondary school maths student | be able to solve quadratic equations | complete my homework as fast as possible and as correctly as possible |
+
## Non-Functional Requirements
-{Give non-functional requirements}
+* Notes can be ported when program starts on a new device.
+* The program should terminate and print an error message when it takes to long to process user inputs.
+* The program should be straightforward and concise; No doubts on how to use the program.
+* Capabilities of the program are made known to the users.
+* Program is to implement features related to studying and maths only. E.g. A step tracker that tracks number of steps
+walked is out of scope.
## Glossary
-* *glossary item* - Definition
+* *x* - input to the trigonometric function, sin(freqInHz* *x*+phase).
+* *y* - output of the trigonometric function above.
+* *xPixel* - *x* value is scaled to position of the x position of the screen.
+* *yPixel* - *y* value is scaled to position of the y position of the screen.
## Instructions for manual testing
-{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing}
+- Download the latest release of BadMaths [here](https://github.com/AY2223S2-CS2113-F10-2/tp/releases).
+- Save the java file to a new folder.
+- Open command prompt by typing `cmd` in the Windows search bar.
+- Navigate to the folder via `cd "folder path"`. (eg. `cd C:\Users\your_name\Desktop\BadMaths`).
+- Type `java -jar BadMaths.jar` to run BadMaths.
+- Follow the [User Guide](https://github.com/AY2223S2-CS2113-F10-2/tp/blob/master/docs/UserGuide.md) to begin testing.
diff --git a/docs/ImagesForUserGuide/Graph_eg_output_1.png b/docs/ImagesForUserGuide/Graph_eg_output_1.png
new file mode 100644
index 0000000000..2436201a70
Binary files /dev/null and b/docs/ImagesForUserGuide/Graph_eg_output_1.png differ
diff --git a/docs/ImagesForUserGuide/Graph_eg_output_2.png b/docs/ImagesForUserGuide/Graph_eg_output_2.png
new file mode 100644
index 0000000000..62da5a1b6c
Binary files /dev/null and b/docs/ImagesForUserGuide/Graph_eg_output_2.png differ
diff --git a/docs/ImagesForUserGuide/Graph_eg_output_3.png b/docs/ImagesForUserGuide/Graph_eg_output_3.png
new file mode 100644
index 0000000000..ef1fca34c5
Binary files /dev/null and b/docs/ImagesForUserGuide/Graph_eg_output_3.png differ
diff --git a/docs/Profile pictures/Seungjun_pic.jpg b/docs/Profile pictures/Seungjun_pic.jpg
new file mode 100644
index 0000000000..82544708ae
Binary files /dev/null and b/docs/Profile pictures/Seungjun_pic.jpg differ
diff --git a/docs/Profile pictures/khooyourun_pic.png b/docs/Profile pictures/khooyourun_pic.png
new file mode 100644
index 0000000000..a9dee411d5
Binary files /dev/null and b/docs/Profile pictures/khooyourun_pic.png differ
diff --git a/docs/Profile pictures/wilson_pic.png b/docs/Profile pictures/wilson_pic.png
new file mode 100644
index 0000000000..3cd59a1755
Binary files /dev/null and b/docs/Profile pictures/wilson_pic.png differ
diff --git a/docs/Profile pictures/yc_pic.png b/docs/Profile pictures/yc_pic.png
new file mode 100644
index 0000000000..db46ce8b55
Binary files /dev/null and b/docs/Profile pictures/yc_pic.png differ
diff --git a/docs/Profile pictures/ziqiuzeng_pic.png b/docs/Profile pictures/ziqiuzeng_pic.png
new file mode 100644
index 0000000000..5959c52f02
Binary files /dev/null and b/docs/Profile pictures/ziqiuzeng_pic.png differ
diff --git a/docs/README.md b/docs/README.md
index bbcc99c1e7..2caa21b3ba 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,6 +1,44 @@
-# Duke
+# _BadMaths_ ➕➖✖️➗
+
+BadMaths is an integrated study tool that performs Mathematical Operations and contains various features for note-taking.
+
+To help you get started, our team has put together this user guide to guide you on the steps to operate BadMaths for your study woes.
+
+## Setting up
+
+Prerequisites: JDK 11 (use the exact version), update Intellij to the most recent version.
+
+1. **Ensure Intellij JDK 11 is defined as an SDK**, as described [here](https://www.jetbrains.com/help/idea/sdk.html#set-up-jdk) -- this step is not needed if you have used JDK 11 in a previous Intellij project.
+2. Download the latest JAR release [here](https://github.com/AY2223S2-CS2113-F10-2/tp/releases).
+3. Copy the JAR file into an empty folder.
+4. Open up a command window in that folder and run the following command:
+```
+java -jar BadMaths.jar
+```
+If the set-up is correct, you should see the following:
+```
+____ _ __ __ _ _
+| _ \ | | | \/ | | | | |
+| |_) | __ _ __| | | \ / | __ _| |_| |__ ___
+| _ < / _` |/ _` | | |\/| |/ _` | __| '_ \/ __|
+| |_) | (_| | (_| | | | | | (_| | |_| | | \__ \
+|____/ \__,_|\__,_| |_| |_|\__,_|\__|_| |_|___/
+You can type 'Help' to learn what I can do for you :)
+```
+
+## Features (v2.1)
+#### Monday, April 10, 2023
+
+1. **Basic mathematical operations**
+ - Analyse trigonometry equations / sinusoidal signals
+ - Solve quadratic equations
+ - Solve matrix calculations
+2. **Notes taking**
+ - Store, delete and list notes
+ - Mark or unmark the notes as done
+ - Rank and display notes based on priority
+ - Find notes based on keywords
-{Give product intro here}
Useful links:
* [User Guide](UserGuide.md)
diff --git a/docs/SequenceDiagrams/GraphSequence.png b/docs/SequenceDiagrams/GraphSequence.png
new file mode 100644
index 0000000000..c351f822df
Binary files /dev/null and b/docs/SequenceDiagrams/GraphSequence.png differ
diff --git a/docs/SequenceDiagrams/MatrixDG.png b/docs/SequenceDiagrams/MatrixDG.png
new file mode 100644
index 0000000000..baa11433e2
Binary files /dev/null and b/docs/SequenceDiagrams/MatrixDG.png differ
diff --git a/docs/SequenceDiagrams/Quadratic.png b/docs/SequenceDiagrams/Quadratic.png
new file mode 100644
index 0000000000..9efc2b5a5e
Binary files /dev/null and b/docs/SequenceDiagrams/Quadratic.png differ
diff --git a/docs/SequenceDiagrams/Store_sequence_diagram.png b/docs/SequenceDiagrams/Store_sequence_diagram.png
new file mode 100644
index 0000000000..9cef22530d
Binary files /dev/null and b/docs/SequenceDiagrams/Store_sequence_diagram.png differ
diff --git a/docs/SequenceDiagrams/invalid_file_handler_sequence_diagram.png b/docs/SequenceDiagrams/invalid_file_handler_sequence_diagram.png
new file mode 100644
index 0000000000..2f4c9598d3
Binary files /dev/null and b/docs/SequenceDiagrams/invalid_file_handler_sequence_diagram.png differ
diff --git a/docs/SequenceDiagrams/load_sequence_diagram.png b/docs/SequenceDiagrams/load_sequence_diagram.png
new file mode 100644
index 0000000000..5e9defc4b8
Binary files /dev/null and b/docs/SequenceDiagrams/load_sequence_diagram.png differ
diff --git a/docs/SequenceDiagrams/note_parser_sequence_diagram.png b/docs/SequenceDiagrams/note_parser_sequence_diagram.png
new file mode 100644
index 0000000000..8728cb6271
Binary files /dev/null and b/docs/SequenceDiagrams/note_parser_sequence_diagram.png differ
diff --git a/docs/UmlFiles/MatrixClassDiagram.puml b/docs/UmlFiles/MatrixClassDiagram.puml
new file mode 100644
index 0000000000..d906af23f1
--- /dev/null
+++ b/docs/UmlFiles/MatrixClassDiagram.puml
@@ -0,0 +1,106 @@
+@startuml
+'https://plantuml.com/class-diagram
+
+!pragma layout smetana
+
+class Calculator {
+ + logger : Logger
+ + run()
+}
+
+class Parser {
+ + check : ExceptionChecker
+ + ep : ExceptionPrinter
+ + parse() : Tensor2D
+ + parseOp() : CalType
+ + parseMatrix() : Tensor2D
+}
+
+class Execute {
+ + execute() : Tensor2D
+ + executeMul() : Tensor2D
+ + executeAdd() : Tensor2D
+ + executeSub() : Tensor2D
+ + executeDot() : Tensor2D
+ + executeTranspose() : Tensor2D
+}
+
+class Calculate {
+ + check : ExceptionChecker
+ + ep : ExceptionPrinter
+ + logger : Logger
+ + mul() : Tensor2D
+ + add() : Tensor2D
+ + sub() : Tensor2D
+ + dot() : Tensor2D
+}
+
+class Tensor2D {
+ + tensor : int[][]
+ + shape : Shape
+ + shape() : Shape
+ + row() : int
+ + column() : int
+ + tensor() : int[][]
+ + get() : int
+ + t() : Tensor2D
+ + toString()
+}
+
+class Shape {
+ + row : int
+ + column : int
+ + getRow() : int
+ + getColumn() : int
+ + toString()
+}
+
+class ExceptionChecker{
+ + checkShapeMismatch()
+ + checkUnknownOperator()
+ + checkMatrixFormat()
+}
+
+class ExceptionPrinter{
+ + printShapeMismatchExceptionLog()
+ + printUnknownOperatorExceptionLog()
+ + printMatrixShapeExceptionLog()
+ + printMatrixFormatExceptionLog()
+ + printMatrixNumericExceptionLog()
+}
+
+class Ui{
+ + printResult()
+}
+
+class MatrixFormatException
+class MatrixShapeException
+class ShapeMismatchException
+class UnknownOperatorException
+
+abstract Tensor {
+ + shape()
+ + toString()
+}
+
+Ui <-- "print 0..1"Calculator
+Parser <-- "parser 0..1"Calculator
+Execute <-- "execute 0..1"Parser
+Parser <.. Execute
+Tensor2D <-- "2D tensor 1..*"Parser
+Tensor2D "2D tensor 1..*"<-- Execute
+Tensor2D "2D tensor 1..*"<.. Calculate
+Calculate "calculate 0..1"<-- Execute
+Tensor2D "2D tensor 1..*"<-- Tensor2D
+Shape "shape 1"<-- Tensor2D
+Tensor2D <|-- Tensor
+ExceptionChecker "0..1"<-- Parser
+ExceptionChecker "0..1"<-- Calculate
+ExceptionPrinter "0..1"<-- Parser
+ExceptionPrinter "0..1"<-- Calculate
+MatrixFormatException "exception 0..1"<..ExceptionChecker
+MatrixShapeException "exception 0..1"<..ExceptionChecker
+ShapeMismatchException "exception 0..1"<..ExceptionChecker
+UnknownOperatorException "exception 0..1"<..ExceptionChecker
+
+@enduml
\ No newline at end of file
diff --git a/docs/UmlFiles/MatrixDG.puml b/docs/UmlFiles/MatrixDG.puml
new file mode 100644
index 0000000000..a2f7bdaf85
--- /dev/null
+++ b/docs/UmlFiles/MatrixDG.puml
@@ -0,0 +1,112 @@
+@startuml
+'https://plantuml.com/sequence-diagram
+
+Command -> Calculator : run()
+activate Calculator
+
+Calculator --> Ui : Ui()
+activate Ui
+Ui --> Calculator
+deactivate Ui
+
+Calculator --> Parser : Parser()
+activate Parser
+Parser --> Calculator
+deactivate Parser
+
+Calculator -> Parser : parse(toDo)
+activate Parser
+
+Parser --> Execute : Execute()
+activate Execute
+Execute --> Parser
+deactivate Execute
+
+alt ADD
+ Parser -> Execute : executeAdd(command)
+ activate Execute
+
+ Execute --> Calculate : Calculate()
+ activate Calculate
+ Calculate --> Execute
+ deactivate Calculate
+
+ Execute -> Execute : executeTranspose(operator[0])
+ Execute -> Execute : executeTranspose(operator[1])
+
+ Execute -> Calculate : add(t1, t2)
+ activate Calculate
+ Calculate -> Execute : result
+ deactivate Calculate
+
+ Execute -> Parser : result
+ deactivate Execute
+else SUB
+ Parser -> Execute : executeSub(command)
+ activate Execute
+
+ Execute --> Calculate : Calculate()
+ activate Calculate
+ Calculate --> Execute
+ deactivate Calculate
+
+ Execute -> Execute : executeTranspose(operator[0])
+ Execute -> Execute : executeTranspose(operator[1])
+
+ Execute -> Calculate : sub(t1, t2)
+ activate Calculate
+ Calculate -> Execute : result
+ deactivate Calculate
+
+ Execute -> Parser : result
+ deactivate Execute
+else MUL
+ Parser -> Execute : executeMul()
+ activate Execute
+
+ Execute --> Calculate : Calculate()
+ activate Calculate
+ Calculate --> Execute
+ deactivate Calculate
+
+ Execute -> Execute : executeTranspose(operator[0])
+ Execute -> Execute : executeTranspose(operator[1])
+
+ Execute -> Calculate : mul(t1, t2)
+ activate Calculate
+ Calculate -> Execute : result
+ deactivate Calculate
+
+ Execute -> Parser : result
+ deactivate Execute
+else DOT
+ Parser -> Execute : executeDot()
+ activate Execute
+
+ Execute --> Calculate : Calculate()
+ activate Calculate
+ Calculate --> Execute
+ deactivate Calculate
+
+ Execute -> Execute : executeTranspose(operator[0])
+ Execute -> Execute : executeTranspose(operator[1])
+
+ Execute -> Calculate : dot(t1, t2)
+ activate Calculate
+ Calculate -> Execute : result
+ deactivate Calculate
+
+ Execute -> Parser : result
+ deactivate Execute
+end
+
+Parser -> Calculator : result
+
+
+Calculator -> Ui : printResult(result)
+activate Ui
+deactivate Ui
+
+deactivate Calculator
+
+@enduml
\ No newline at end of file
diff --git a/docs/UmlFiles/QuadraticClassDiagram.puml b/docs/UmlFiles/QuadraticClassDiagram.puml
new file mode 100644
index 0000000000..10b6a255b8
--- /dev/null
+++ b/docs/UmlFiles/QuadraticClassDiagram.puml
@@ -0,0 +1,29 @@
+@startuml
+'https://plantuml.com/class-diagram
+
+class Quadratic {
+ + toDo: String
+ + quadraticFormula(): ArrayList
+ + minMaxPointFinder(): String
+ + printAnswer()
+ + solveQuadratic()
+}
+class QuadraticParser {
+ + findA(): double
+ + findSignOfB(): String
+ + findStringOfB(): String
+ + findB(): double
+ + findSignOfC(): String
+ + findStringOfC(): String
+ + findC(): double
+}
+class Ui {
+ + printQuadraticFormatError()
+ + printQuadraticAnswer()
+}
+
+Quadratic <|-- QuadraticParser
+Ui <-- Quadratic
+
+
+@enduml
diff --git a/docs/UmlFiles/QuadraticSolver.puml b/docs/UmlFiles/QuadraticSolver.puml
new file mode 100644
index 0000000000..f6037e19e6
--- /dev/null
+++ b/docs/UmlFiles/QuadraticSolver.puml
@@ -0,0 +1,44 @@
+@startuml
+'https://plantuml.com/sequence-diagram
+-> ":Command"
+activate ":Command"
+":Command" -> ":Quadratic": quadratic.solveQuadratic()
+activate ":Quadratic"
+":Quadratic" -> ":QuadraticParser"
+activate ":QuadraticParser"
+activate ":Ui"
+":QuadraticParser" -> ":QuadraticParser" : findA()
+activate ":QuadraticParser" #FFBBBB
+deactivate ":QuadraticParser"
+":QuadraticParser" -> ":QuadraticParser" : findB()
+activate ":QuadraticParser" #FFBBBB
+deactivate ":QuadraticParser"
+":QuadraticParser" -> ":QuadraticParser" : findC()
+activate ":QuadraticParser" #FFBBBB
+deactivate ":QuadraticParser"
+":QuadraticParser" --> ":Quadratic"
+deactivate ":QuadraticParser"
+":Quadratic" -> ":Quadratic": quadraticFormula()
+activate ":Quadratic" #FFBBBB
+deactivate ":Quadratic"
+":Quadratic" -> ":Quadratic": minMaxPointFinder()
+activate ":Quadratic" #FFBBBB
+deactivate ":Quadratic"
+":Quadratic" -> ":Quadratic": printAnswer()
+activate ":Quadratic" #FFBBBB
+":Quadratic" -> ":Ui": Ui.printQuadraticAnswer()
+activate ":Ui" #FFBBBB
+":Ui" --> ":Quadratic"
+deactivate ":Ui"
+deactivate ":Quadratic"
+opt Exceptions
+":Quadratic" -> ":Ui": printQuadraticFormatError()
+activate ":Ui" #FFBBBB
+":Ui" --> ":Quadratic"
+deactivate ":Ui"
+end opt
+":Quadratic" --> ":Command"
+deactivate ":Quadratic"
+deactivate ":Command"
+deactivate ":Ui"
+@enduml
diff --git a/docs/UmlFiles/Store.puml b/docs/UmlFiles/Store.puml
new file mode 100644
index 0000000000..b216786691
--- /dev/null
+++ b/docs/UmlFiles/Store.puml
@@ -0,0 +1,27 @@
+@startuml
+'https://plantuml.com/sequence-diagram
+
+@startuml
+title Sequence Diagram for Store
+actor User
+
+User -> ":Store" **: Store(notes, toDo)
+User -> ":Store":storeNotes()
+activate ":Store"
+alt isInvalidTodo(toDo) is "Invalid todo"
+ ":Store" -> ":Ui" : Ui.printIncorrectFormatEntered()
+ activate ":Ui"
+ deactivate ":Ui"
+ else
+ ":Store" -> ":notes": notes.add(toDo)
+ activate ":notes"
+ deactivate ":notes"
+ ":Store" -> ":Ui": Ui.printAddNote(toDo, notes.getSize());
+ activate ":Ui"
+ deactivate ":Ui"
+ ":Store" -> ":NotesFileWriter": NotesFileWriter.saveFile(filePath, notes.getAll())
+ activate ":NotesFileWriter"
+ deactivate ":NotesFileWriter"
+ end
+deactivate ":Store"
+@enduml
\ No newline at end of file
diff --git a/docs/UmlFiles/TrigoGraph.puml b/docs/UmlFiles/TrigoGraph.puml
new file mode 100644
index 0000000000..33b1e81809
--- /dev/null
+++ b/docs/UmlFiles/TrigoGraph.puml
@@ -0,0 +1,75 @@
+@startuml
+
+
+[->":TrigoGraph": startGraphAnalysis()
+activate ":TrigoGraph"
+
+":TrigoGraph"-> ":TrigoGraphAnalyser"**:TrigoGraphAnalyser(trigoEqn)
+
+activate ":TrigoGraphAnalyser"
+":TrigoGraphAnalyser" --> ":TrigoGraph"
+deactivate ":TrigoGraphAnalyser"
+opt analyser.canStartAnalyser
+":TrigoGraph" -> ":TrigoGraph" :getGraphDetails(analyser)
+activate ":TrigoGraph"
+
+":TrigoGraph" -> ":TrigoGraphAnalyser": getAmplitude()
+activate ":TrigoGraphAnalyser"
+deactivate ":TrigoGraphAnalyser"
+
+":TrigoGraph" -> ":TrigoGraphAnalyser": getFreq()
+activate ":TrigoGraphAnalyser"
+deactivate ":TrigoGraphAnalyser"
+
+":TrigoGraph" -> ":TrigoGraphAnalyser": getPhase()
+activate ":TrigoGraphAnalyser"
+deactivate ":TrigoGraphAnalyser"
+
+":TrigoGraph" -> ":TrigoGraphAnalyser": getVerticalShift()
+activate ":TrigoGraphAnalyser"
+deactivate ":TrigoGraphAnalyser"
+
+":TrigoGraph" -> ":TrigoGraphAnalyser": getTrigonometry()
+activate ":TrigoGraphAnalyser"
+deactivate ":TrigoGraphAnalyser"
+
+":TrigoGraph" -> ":TrigoGraph"
+deactivate ":TrigoGraph"
+
+":TrigoGraph" -> ":TrigoGraph": printGraphDetails()
+activate ":TrigoGraph"
+
+":TrigoGraph" -> ":Ui": printAmplitude(amplitude)
+activate ":Ui"
+deactivate ":Ui"
+
+":TrigoGraph" -> ":Ui": printFrequency(frequency)
+activate ":Ui"
+deactivate ":Ui"
+
+":TrigoGraph" -> ":Ui": printPhase(phase)
+activate ":Ui"
+deactivate ":Ui"
+
+":TrigoGraph" -> ":Ui": printVerticalShift(verticalShift)
+activate ":Ui"
+deactivate ":Ui"
+
+":TrigoGraph" -> ":TrigoGraph"
+deactivate ":TrigoGraph"
+
+":TrigoGraph" -> TrigoGraphVisualiser**: TrigoGraphVisualiser(amplitude,phase,frequency,verticalShift,trig)
+activate TrigoGraphVisualiser
+TrigoGraphVisualiser -->> ":TrigoGraph"
+deactivate TrigoGraphVisualiser
+
+":TrigoGraph" -> TrigoGraphVisualiser: startVisualiser()
+activate TrigoGraphVisualiser
+
+deactivate TrigoGraphVisualiser
+end opt
+
+
+deactivate ":TrigoGraph"
+
+@enduml
diff --git a/docs/UmlFiles/UserInputHandlingClassDiagram.puml b/docs/UmlFiles/UserInputHandlingClassDiagram.puml
new file mode 100644
index 0000000000..4fac000154
--- /dev/null
+++ b/docs/UmlFiles/UserInputHandlingClassDiagram.puml
@@ -0,0 +1,33 @@
+@startuml
+'https://plantuml.com/class-diagram
+
+class BadMaths {
+ + commandChecker()
+ + main()
+}
+
+class Parser {
+ # userInput: String
+ + getCommand(): String
+ + getToDo(): String
+}
+
+class Ui {
+ + printIncorrectFormatEntered()
+ + printWelcomeMessage()
+}
+
+class Command {
+ # command: String
+ # toDo: String
+ + setCommand()
+ + setToDo()
+ + executeCommand()
+}
+
+Parser <-- BadMaths
+Command "1" <-- BadMaths
+Ui "1" <-- BadMaths
+
+
+@enduml
diff --git a/docs/UmlFiles/graph_class_diagram.puml b/docs/UmlFiles/graph_class_diagram.puml
new file mode 100644
index 0000000000..d0ee9b1080
--- /dev/null
+++ b/docs/UmlFiles/graph_class_diagram.puml
@@ -0,0 +1,51 @@
+@startuml
+'https://plantuml.com/class-diagram
+
+class TrigoGraph {
+ - trigoEqn: String
+ - amplitude: double
+ - frequency: double
+ - phase: double
+ - verticalShift: double
+ - trig: String
+ + TrigoGraph: void(trigoEqn)
+ + startGraphAnalysis: void()
+ + getGraphDetails: void(analyser)
+ + printGraphDetails: void()
+}
+class TrigoGraphAnalyser {
+ - trigoEqn: String
+ - amplitude: double
+ - freq: double
+ - phase: double
+ - verticalShift: double
+ - trig: String
+ + canStartAnalyser: boolean()
+}
+class TrigoGraphVisualiser {
+ - amplitude: double
+ - freqInHz: double
+ - phase: double
+ - verticalShift: double
+ - trig: String
+ + startVisualiser: void()
+ # paintComponent: void(g)
+}
+class Ui {
+ + printIncorrectFormatEntered: void()
+ + printAmplitude: void(amplitude: double)
+ + printFrequency: void(frequency: double)
+}
+class JFrame
+abstract Graphics
+
+
+
+
+TrigoGraph ..> Ui
+TrigoGraph --> "visualiser 0..1"TrigoGraphVisualiser
+TrigoGraph --> "analyser 0..1"TrigoGraphAnalyser
+TrigoGraphVisualiser --> JFrame
+TrigoGraphVisualiser ..> Graphics
+
+@enduml
\ No newline at end of file
diff --git a/docs/UmlFiles/invalid_file_handler_sequence_diagram.puml b/docs/UmlFiles/invalid_file_handler_sequence_diagram.puml
new file mode 100644
index 0000000000..5ee2091c81
--- /dev/null
+++ b/docs/UmlFiles/invalid_file_handler_sequence_diagram.puml
@@ -0,0 +1,33 @@
+@startuml
+'https://plantuml.com/sequence-diagram
+
+ --> ":InvalidNotesFileHandler": responseHandler(path, notes)
+ activate ":InvalidNotesFileHandler"
+ ":InvalidNotesFileHandler" -> ":Scanner": Scanner()
+ activate ":Scanner"
+ ":Scanner" -> ":Scanner": nextLine()
+ alt userInput is "y"
+ ":InvalidNotesFileHandler" -> ":PrintWriter": PrintWriter(path)
+ activate ":PrintWriter"
+ ":PrintWriter" -> ":PrintWriter": print("")
+ ":PrintWriter" -> ":PrintWriter": close()
+ ":PrintWriter" --> ":InvalidNotesFileHandler"
+ deactivate ":PrintWriter"
+ ":InvalidNotesFileHandler" -> ":ArrayList": clear()
+ activate ":ArrayList"
+ ":ArrayList" --> ":InvalidNotesFileHandler"
+ deactivate ":ArrayList"
+ else userInput is "n"
+ ":InvalidNotesFileHandler" -> ":Timer": Timer()
+ activate ":Timer"
+ ":InvalidNotesFileHandler" -> ":TimerTask": TimerTask()
+ activate ":TimerTask"
+ ":InvalidNotesFileHandler" -> ":Timer": schedule(TimerTask, delay)
+ ":Timer" -> ":TimerTask": run()
+ ":TimerTask" -> :exit(0)
+ deactivate ":Timer"
+ deactivate ":TimerTask"
+ end
+ deactivate ":Scanner"
+ deactivate ":InvalidNotesFileHandler"
+@enduml
\ No newline at end of file
diff --git a/docs/UmlFiles/load_sequence_diagram.puml b/docs/UmlFiles/load_sequence_diagram.puml
new file mode 100644
index 0000000000..b6c92c2366
--- /dev/null
+++ b/docs/UmlFiles/load_sequence_diagram.puml
@@ -0,0 +1,66 @@
+@startuml
+activate System
+
+--> ":NotesFileParser": loadFile(path)
+activate ":NotesFileParser"
+":NotesFileParser" -> ":ArrayList": ArrayList()
+activate ":ArrayList"
+":ArrayList" --> ":NotesFileParser"
+deactivate ":ArrayList"
+":NotesFileParser" -> ":Scanner": Scanner(path)
+activate ":Scanner"
+":NotesFileParser" -> ":Scanner": scanner.hasNextLine()
+loop for each line
+ ":Scanner" -> ":Scanner": scanner.nextLine()
+ ":NotesFileParser" -> ":NoteParser": parseNoteString(noteScanner)
+ activate ":NoteParser"
+ ":NoteParser" -> ":String": split()
+ activate ":String"
+ ":String" --> ":NoteParser"
+ deactivate ":String"
+ alt noteInfo.length == 4
+ ":NoteParser" -> ":Note": Note()
+ activate ":Note"
+ ":Note" --> ":NoteParser"
+ deactivate ":Note"
+ ":NoteParser" --> ":NotesFileParser": note
+ ":NotesFileParser" -> ":ArrayList": add()
+ activate ":ArrayList"
+ ":ArrayList" --> ":NotesFileParser"
+ deactivate ":ArrayList"
+ else noteInfo.length != 4
+ ":NoteParser" -> ":InvalidFormatException": throw exception
+ activate ":InvalidFormatException"
+ ":InvalidFormatException" --> ":NoteParser"
+ deactivate ":InvalidFormatException"
+ end
+end
+deactivate ":NoteParser"
+deactivate ":Scanner"
+
+alt file is invalid
+ ":NotesFileParser" -> ":InvalidNotesFileHandler": responseHandler(path, notes)
+ activate ":InvalidNotesFileHandler"
+ alt userInput is "y"
+ ":InvalidNotesFileHandler" -> ":PrintWriter": PrintWriter(path)
+ activate ":PrintWriter"
+ ":PrintWriter" --> ":InvalidNotesFileHandler"
+ deactivate ":PrintWriter"
+ ":InvalidNotesFileHandler" -> ":ArrayList": clear()
+ activate ":ArrayList"
+ ":ArrayList" --> ":InvalidNotesFileHandler"
+ deactivate ":ArrayList"
+ else userInput is "n"
+ ":InvalidNotesFileHandler" -> System: exit(0)
+ deactivate ":InvalidNotesFileHandler"
+ end
+else file is valid
+ <-- ":NotesFileParser": notes
+end
+
+deactivate ":NotesFileParser"
+
+deactivate System
+
+@enduml
+
diff --git a/docs/UmlFiles/note_parser_sequence_diagram.puml b/docs/UmlFiles/note_parser_sequence_diagram.puml
new file mode 100644
index 0000000000..3097d8f1ee
--- /dev/null
+++ b/docs/UmlFiles/note_parser_sequence_diagram.puml
@@ -0,0 +1,59 @@
+@startuml
+ --> ":NoteParser": parseNoteString(noteScanner)
+ activate ":NoteParser"
+ ":NoteParser" -> ":String": split()
+ activate ":String"
+ ":String" --> ":NoteParser"
+ deactivate ":String"
+ alt noteInfo.length == 4
+ alt priorityStr is valid
+ ":NoteParser" -> ":NotePriority": Priority.valueOf(priorityStr)
+ activate ":NotePriority"
+ ":NotePriority" --> ":NoteParser"
+ deactivate ":NotePriority"
+ else priorityStr is invalid
+ ":NoteParser" -> ":InvalidFormatException": throw exception
+ activate ":InvalidFormatException"
+ ":InvalidFormatException" --> ":NoteParser"
+ deactivate ":InvalidFormatException"
+ end
+ alt isDoneStr is valid
+ ":NoteParser" -> ":String": equals()
+ activate ":String"
+ ":String" --> ":NoteParser"
+ deactivate ":String"
+ else isDoneStr is invalid
+ ":NoteParser" -> ":InvalidFormatException": throw exception
+ activate ":InvalidFormatException"
+ ":InvalidFormatException" --> ":NoteParser"
+ deactivate ":InvalidFormatException"
+ end
+ alt reviewCountStr is valid
+ ":NoteParser" -> ":Integer": parseInt(reviewCountStr)
+ activate ":Integer"
+ ":Integer" --> ":NoteParser"
+ deactivate ":Integer"
+ else reviewCountStr is invalid
+ ":NoteParser" -> ":InvalidFormatException": throw exception
+ activate ":InvalidFormatException"
+ ":InvalidFormatException" --> ":NoteParser"
+ deactivate ":InvalidFormatException"
+ end
+ ":NoteParser" -> ":Note": Note(noteStr, priority)
+ activate ":Note"
+ ":Note" -> ":Note": setReviewCount(reviewCount)
+ alt isDone = true
+ ":Note" -> ":Note": markAsDone()
+ else isDone = false
+ ":Note" -> ":Note": markAsNotDone()
+ end
+ ":Note" --> ":NoteParser"
+ deactivate ":Note"
+ <-- ":NoteParser": note
+ else noteInfo.length != 4
+ ":NoteParser" -> ":InvalidFormatException": throw exception
+ activate ":InvalidFormatException"
+ ":InvalidFormatException" --> ":NoteParser"
+ deactivate ":InvalidFormatException"
+ end
+@enduml
\ No newline at end of file
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index abd9fbe891..6745fc2a7f 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -1,42 +1,773 @@
-# User Guide
+# GitHub User Guide for BadMaths ➕➖✖️➗
-## Introduction
+## Table of Contents:
-{Give a product intro}
+
+ * [Introduction 🧮](#introduction-)
+ * [Quick Start](#quick-start)
+ * [Features](#features)
+ * [1) Graph Analyser and Visualiser: `Graph`](#1-graph-analyser-and-visualiser-graph)
+ * [2) Matrix Calculation: `Matrix`](#2-matrix-calculation-matrix)
+ * [3) Store Notes: `Store`](#3-store-notes-store)
+ * [4) Display All Notes: `List`](#4-display-all-notes-list)
+ * [5) Display A Specific Note: `List `](#5-display-a-specific-note-list-index)
+ * [6) Delete Notes: `Delete `](#6-delete-notes-delete-index)
+ * [7) Clear All Notes Stored In Notes List `Clear`](#7-clear-all-notes-stored-in-notes-list-clear)
+ * [8) Mark Notes: `Mark`](#8-mark-notes-mark)
+ * [9) Unmark Notes: `Unmark`](#9-unmark-notes-unmark)
+ * [10) List All Items Marked As Completed: `FindMark`](#10-list-all-items-marked-as-completed-findmark)
+ * [11) List All Notes That Are Not Marked As Completed: `FindUnmark`](#11-list-all-notes-that-are-not-marked-as-completed-findunmark)
+ * [12) Find Notes Using Keyword: `FindInfo`](#12-find-notes-using-keyword-findinfo)
+ * [13) Prioritize A Note](#13-prioritize-a-note)
+ * [14) Display All Notes Based On All Priority Types: `Rank Priority`](#14-display-all-notes-based-on-all-priority-types-rank-priority)
+ * [15) Display All Notes Based On Review Count: `Rank Review Count`](#15-display-all-notes-based-on-review-count-rank-review-count)
+ * [16) Display All Notes Of A Certain Priority Type: `FindPrior`](#16-display-all-notes-of-a-certain-priority-type-findprior)
+ * [17) Solving Quadratic Equations: `Quadratic`](#17-solving-quadratic-equations-quadratic)
+ * [18) Command History `History`](#18-command-history-history)
+ * [19) Help Manual `Help`](#19-help-manual-help)
+ * [20) Exit BadMaths `Bye`](#20-exit-badmaths-bye)
+ * [FAQ](#faq)
+ * [Command Summary](#command-summary)
+ * [General](#general)
+ * [Notes](#notes)
+ * [Graph](#graph)
+ * [Quadratic](#quadratic)
+
+
+## Introduction 🧮
+
+Hello! Welcome to BadMaths! BadMaths is an integrated study tool that performs Mathematical Operations and contains
+various features for note-taking.
+
+To help you get started, our team has put together this user guide to guide you on
+the steps to operate BadMaths for your study woes.
## Quick Start
-{Give steps to get started quickly}
+Before you start using BadMaths, make sure you have the following ready!
1. Ensure that you have Java 11 or above installed.
-1. Down the latest version of `Duke` from [here](http://link.to/duke).
+2. Down the latest version of `BadMaths` from [here](https://github.com/AY2223S2-CS2113-F10-2/tp/releases).
+
+## Features
+
+### 1) Graph Analyser and Visualiser: `Graph`
+This feature accepts a trigonometry equation (Sinusoidal signal) and outputs the amplitude, frequency, phase, and vertical shift.
+It also displays the image of the corresponding graph.
+
+Format: `Graph [Amplitude]*[Trigo]([Frequency]*x[sign][PhaseShift])[sign][VerticalShift]`
+
+* `Amplitude` can be any positive number. E.g. `15.5`, `4`, `0`
+* `Trigo` can be sin, cos or tan.
+* `Frequency` can be any positive number (more than 0). E.g. `100`
+ * When entering frequency, one can include 𝜋 by typing `2*pi*x` instead of `6.283*x`
+* `PhaseShift`, `VerticalShift` can be any positive number. E.g. `15.1`, `4`, `0`,`1`
+* `sign` can be + or - .
+* `[` and `]` are not needed when entering the input.
+* Some form of elimination is possible:
+ * When `Amplitude` is 1, `1*cos(1*x)` can be shortened to `cos(1*x)`
+ * When `PhaseShift` or `verticalShift` is 0, `[sign][PhaseShift]` or `[sign][VerticalShift]` are not needed.
+
+**Note: Accuracy of graph drawn is up to 4 digits (Thousand place) for numerical inputs. E.g. `9999`.**
+
+
+Example input 1:
+```
+Graph 2985*sin(5999*x+2665)-8678
+```
+Example output 1:
+```
+This is the amplitude: 2985.0
+This is the freq (Hz): 954.7705036082801
+This is the phase: 2665.0
+This is the vertical shift: -8678.0
+```
+
+
+Example input 2:
+```
+Graph 2*sin(5*pi*x-2)+5.6
+```
+Example output 2:
+```
+This is the amplitude: 2.0
+This is the freq (Hz): 2.5
+This is the phase: -2.0
+This is the vertical shift: 5.6
+```
+
+
+Example input 3:
+```
+Graph cos(5*x)
+```
+Example output 3:
+```
+This is the amplitude: 1.0
+This is the freq (Hz): 0.7957747154594768
+This is the phase: 0.0
+This is the vertical shift: 0.0
+```
+
+
+### 2) Matrix Calculation: `Matrix`
+This feature accepts matrix equation and outputs calculation result.
+
+Format: `Matrix [Matrix] [operator] [Matrix]`
+
+* `[Matrix]` is the 2 dimensional matrix with integer elements. When you declare the matrix, you should follow the matrix format below:
+ ```
+ [1,2;3,4]
+ ```
+ * You should separate the elements with comma (,) in the single row.
+ * You should separate the rows with the semicolons.
+
+ ```
+ [1,2;3,4].T
+ ```
+ * You can declare transposed matrix with the transpose annotation `.T`.
+ * Transposed matrix above is equal with matrix `[1,3;2,4]`.
+
+ > NOTE : The entities of matrix should be all integer.
+
+ > NOTE : The length of every rows in matrix should be the same with each other.
+
+* `[operator]` is the matrix operator. You can use 4 operators below:
+ * `.*` : matrix multiplication
+ * `*` : element wise product
+ * `+` : matrix addition
+ * `-` : matrix subtraction
+
+ > NOTE : Shape of the two operands should be properly matched with each other for the given operator.
+ > For the `.*` operator, the number of the columns of operand1 should be the same with the number of the rows of operand2.
+ > For the `*`, `+`, and `-` operators, the shape of the two operands should be identical.
+
+#### You can see the right examples of the matrx calculation below:
+* Examples for the matrix multiplication
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4] .* [4,5;6,7]
+ ```
+
+ *Output* :
+ ```
+ Result.
+ 1. shape : 2 x 2
+ 2. value :
+ 0) 16 19
+ 1) 36 43
+ ```
+* Examples for the matrix multiplication with transpose
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4] .* [4,5;6,7].T
+ ```
+
+ *Output* :
+ ```
+ Result.
+ 1. shape : 2 x 2
+ 2. value :
+ 0) 14 20
+ 1) 32 46
+ ```
+* Examples for the matrix element wise product
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4] * [4,5;6,7]
+ ```
+
+ *Output* :
+ ```
+ Result.
+ 1. shape : 2 x 2
+ 2. value :
+ 0) 4 10
+ 1) 18 28
+ ```
+* Examples for the matrix addition
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4] + [4,5;6,7]
+ ```
+
+ *Output* :
+ ```
+ Result.
+ 1. shape : 2 x 2
+ 2. value :
+ 0) 5 7
+ 1) 9 11
+ ```
+* Examples for the matrix subtraction
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4] - [4,5;6,7]
+ ```
+
+ *Output* :
+ ```
+ Result.
+ 1. shape : 2 x 2
+ 2. value :
+ 0) -3 -3
+ 1) -3 -3
+ ```
+
+#### You can see the examples for common mistakes below:
+* Every entities of the matrix should be integer.
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4] .* [4,5;6,a]
+ ```
+ ```
+ Matrix [1,2;3,4] .* [4,5;6,7.1]
+ ```
+
+ *Output* :
+ ```
+
+ Every entities of matrix should be integer.
+ ```
+
+* Length of every rows should be the same with each other.
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4,5] * [4,5;6,7]
+ ```
+
+ *Output* :
+ ```
+
+ Length of every rows should be the same with each other.
+ ```
+
+* There is shape mismatch between t1 and t2 : cannot execute matrix calculation.
+
+ *Input* :
+ ```
+ Matrix [1,2;3,4] .* [1,2,3;3,4,5]
+ ```
+ ```
+ Matrix [1,2;3,4] + [1,2,3;3,4,5]
+ ```
+
+ *Output* :
+ ```
+
+ There is shape mismatch between t1 and t2 : cannot execute matrix calculation.
+ ```
+
+### 3) Store Notes: `Store`
+* Adds a new item to the Notes list.
+* Format: `Store - `
+
+Example input:
+```
+Store isNote
+```
+Expected output:
+```
+You have added this note:
+isNote
+Now you have of notes in the list
+```
+
+### 4) Display All Notes: `List`
+* Display a list of all items stored by user.
+* Format: `List`
+
+Example input:
+```
+List
+```
+Expected output:
+```
+Here are the notes you have stored:
+1. [LOW][N][0]note_item_1
+2. [LOW][N][0]note_item_2
+3. [LOW][N][0]note_item_3
+```
+
+### 5) Display A Specific Note: `List `
+* Display a particular item in the Notes list through index of list item.
+* Format: `List `
+
+Example input:
+```
+List 2
+```
+Expected output:
+```
+Here is the note you are looking for
+2. [LOW][N][0]note_item_2
+```
+
+### 6) Delete Notes: `Delete `
+* Delete a particular item stored in the Notes list through index of list item.
+* Format: `Delete. `
+
+Example input:
+```
+Delete 2
+```
+Expected output:
+```
+You have removed this note:
+[LOW][N][0]note_item_2
+Now you have notes in the list.
+```
+
+### 7) Clear All Notes Stored In Notes List `Clear`
+* Delete all note items stored in Notes List.
+* Format: `Clear`
+
+Example input:
+```
+Clear
+```
+Expected output:
+```
+File content cleared successfully!
+```
+### 8) Mark Notes: `Mark`
+* Mark a particular item in Notes List as completed.
+* The mark bracket will change from `[N]` to `[Y]`.
+* Format: `Mark `
-## Features
+Example input:
+```
+Mark 2
+```
+Expected output:
+```
+You have marked this note as done:
+[LOW][Y][0]note_item_2
+```
+### 9) Unmark Notes: `Unmark`
+* Unmark a particular item in Notes List as incomplete.
+* The mark bracket will change from `[Y]` to `[N]`.
-{Give detailed description of each feature}
+* Format: `Unmark `
-### Adding a todo: `todo`
-Adds a new item to the list of todo items.
+Example input:
+```
+Unmark 2
+```
+Expected output:
+```
+You have unmarked this note:
+[LOW][N][0]note_item_2
+```
+### 10) List All Items Marked As Completed: `FindMark`
+* Display a list of all note items marked as completed.
+* All items with mark bracket `[Y]` will be displayed.
+* Format: `FindMark`
-Format: `todo n/TODO_NAME d/DEADLINE`
+Example input:
+```
+FindMark
+```
+Expected output:
+```
+Here are the notes you are searching for:
+1. [LOW][Y][0]note_item_1
+2. [LOW][Y][0]note_item_3
+```
-* The `DEADLINE` can be in a natural language format.
-* The `TODO_NAME` cannot contain punctuation.
+### 11) List All Notes That Are Not Marked As Completed: `FindUnmark`
+* Display a list of all incomplete note items.
+* All items with mark bracket `[N]` will be displayed.
+* Format: `FindUnmark`
+
+Example input:
+```
+FindUnmark
+```
+Expected output:
+```
+Here are the notes you are searching for:
+1. [LOW][N][0]note_item_2
+```
+
+### 12) Find Notes Using Keyword: `FindInfo`
+* Find items stored in Notes by searching for a keyword.
+* Format: `FindInfo `
+
+Assuming that the List is as follows:
+```
+1. [LOW][N][0]Add
+2. [LOW][N][0]Subtract
+3. [LOW][N][0]Multiply
+```
+Example input:
+```
+FindInfo Add
+```
+Expected output:
+```
+Here are the notes you are searching for:
+1. [LOW][N][0]Add
+```
+
+### 13) Prioritize A Note
+Change the priority of a certain note in the notes list.
+
+Format: ` `
+Example of usage: `High 1`
+
+* The `` must be one of the three: `High`, `Medium`, `Low`.
+
+Example of usage:
+
+`High 1`
+
+Expected outcome:
+
+````
+You have changed its priority to HIGH
+1: [HIGH][N][0]Note 1
+````
+Example of usage:
+
+`Medium 3`
+
+Expected outcome:
+
+````
+You have changed its priority to MEDIUM
+3: [MEDIUM][N][0]Note 3
+````
+
+### 14) Display All Notes Based On All Priority Types: `Rank Priority`
+Display all items stored in the Notes List based on the respective priority rankings.
+
+Format: `Rank Priority`
Example of usage:
-`todo n/Write the rest of the User Guide d/next week`
+`Rank Priority`
+
+Expected outcome:
+````
+High priority notes:
+[HIGH][N][0]note_item_1
+Medium priority notes:
+[MEDIUM][N][0]note_item_2
+Low priority notes:
+[LOW][N][0]note_item_3
+````
+
+### 15) Display All Notes Based On Review Count: `Rank Review Count`
+Display all items stored in the Notes List based on the respective review count rankings.
+
+Format: `Rank Review Count`
+
+Example of usage:
+
+`Rank Priority`
+
+Expected outcome:
+
+````
+Notes sorted by review count:
+note_item_1 (review count: 3)
+note_item_2 (review count: 2)
+note_item_3 (review count: 1)
+````
+
+### 16) Display All Notes Of A Certain Priority Type: `FindPrior`
+* Find all notes stored in the list based on the priority that users are searching for.
+* Format: `FindPrior `
+* The `` must be one of the three types: `High`, `Medium`, `Low`, case-insensitive.
+
+
+Example input:
+```
+FindPrior LOW
+```
+Expected outcome:
+````
+Here are the notes you are searching for:
+1. [LOW][N][0]note_item_1
+2. [LOW][N][0]note_item_2
+3. [LOW][N][0]note_item_3
+````
-`todo n/Refactor the User Guide to remove passive voice d/13/04/2020`
+Example input:
+```
+FindPrior mEdIuM
+```
+Expected outcome:
+````
+Here are the notes you are searching for:
+1. [MEDIUM][N][0]note_item_4
+2. [MEDIUM][N][0]note_item_5
+````
+
+### 17) Solving Quadratic Equations: `Quadratic`
+Solves for `x` in a quadratic equation.
+
+Format: `Quadratic [quadratic equation]`
+
+- `Quadratic` must be in this exact format (With uppercase Q)
+- The quadratic equation must look like this: `2x^2 + 2x + 1` with spaces between each value. Both double and integer
+ numbers are acceptable (eg. `-2.5x^2 + 3 + 1`). Inputting just the sign is also acceptable (eg. `-x^2 + x - 1`).
+
+Examples:
+
+- Input:
+````
+Quadratic 2x^2 + 2x + 1
+````
+- Output:
+````
+x is imaginary.
+````
+- Input:
+````
+Quadratic x^2 + 4x - 5
+````
+- Output:
+````
+x1 = 1.0 , x2 = -5.0
+There is a minimum point: (-2.0, -9.0)
+````
+- Input:
+````
+Quadratic x^2 + 3
+````
+- Output:
+````
+Please use the format as shown below:
+ax^2 + bx + c
+````
+
+### 18) Command History `History`
+* Display a list of Command History that users have
+ entered during the current programme run session.
+* Format: History
+
+Assuming that user have input `Store index` after starting badMaths:
+
+Example input:
+```
+History
+```
+Expected output:
+```
+Here are the list of commands that you have entered so far:
+Store index
+History
+```
+
+### 19) Help Manual `Help`
+* Display the content of Help Manual for BadMaths.
+* Format: `Help`
+
+Example input:
+```
+Help
+```
+Expected output:
+```
+------------------------------------------------------------------
+Hello! Welcome to the Help Manual for BadMaths!
+------------------------------------------------------------------
+1. Type -> Graph [equation] <- to perform graph calculations
+2. Type -> Matrix [equation] <- to perform matrix calculations
+3. Type -> Store [any_string] <- to add notes
+4. Type -> List <- to list all stored notes
+5. Type -> List [index] <- to display a particular note
+6. Type -> Delete [index] <- to delete a particular note
+7. Type -> Clear <- to delete all stored notes
+8. Type -> Mark [index] <- to mark a particular note as completed
+9. Type -> Unmark [index] <- to unmark a particular note as incomplete
+10. Type -> FindMark <- to display a list of all notes marked as completed
+11. Type -> FindUnmark <- to display a list of all notes marked as incomplete
+12. Type -> FindInfo <- to find items stored in Notes through searching for a keyword
+13. Type -> [Priority] [index] <- to change the priority of a note
+14. Type -> Rank Priority <- to display all notes of all priority rankings
+15. Type -> Rank Review Count <- to display all notes ranked by review count
+16. Type -> FindPrior [Priority] <- to display all notes of a certain priority
+17. Type -> Quadratic [equation] <- to perform quadratic calculations
+18. Type -> History <- to display a list of command history
+19. Type -> Help <- to display content of Help Manual
+20. Type -> Bye <- to exit program
+
+-------------------------------------------------------------------
+Thank you for using BadMaths. We hope that BadMaths will be a useful study tool
+in helping you to perform Mathematical Operations.
+For more details, please visit our GitHub website [https://github.com/AY2223S2-CS2113-F10-2/tp].
+If you have any queries on BadMaths, please contact [wilsonleejunwei@u.nus.edu].
+-------------------------------------------------------------------
+```
+
+### 20) Exit BadMaths `Bye`
+* Exit and leave BadMaths:
+* Format: `Bye`
+
+Example input:
+```
+Bye
+```
+Expected outcome:
+````
+Goodbye!
+````
## FAQ
-**Q**: How do I transfer my data to another computer?
+**Q1**: How do I start and run BadMaths?
+
+**A1**:
+
+- Download the latest release of BadMaths [here](https://github.com/AY2223S2-CS2113-F10-2/tp/releases).
+- Save the java file to a new folder.
+- Open command prompt by typing `cmd` in the Windows search bar.
+- Navigate to the folder via `cd "folder path"`. (eg. `cd C:\Users\your_name\Desktop\BadMaths`).
+- Type `java -jar BadMaths.jar` to run BadMaths.
+- Follow the `User Guide` to begin testing.
+
+**Q2**: How do I exit and leave BadMaths?
+
+**A2**: You can terminate the MathHelp programme by simply typing
+`Bye` in the command.
+
+**Q3**: What should I do if the file is corrupted?
+
+**A3**:
+
+- When BadMaths detects that the target file is corrupted, BadMaths will request whether you want to clear the file for
+continual use by print the prompt message
+````
+Sorry, your notes file seems to be corrupted :(
+Do you want to reset the file? (y/n)
+````
+- You can inform BadMaths whether you want to clear the file by typing `y` or `n`.
+- By typing `n` not to empty the file, BadMaths will prompt you for your choice and automatically exit after
+`10 seconds`. In such cases, please correct the file format manually before continuing to use BadMaths.
+- By typing `y` to empty the file, BadMaths will prompt you when the target file is successfully emptied,
+and you will be able to continue using BadMaths by then.
+
+**Q4**: In the matrix calculation, can I declare matrix with 3D dimension or above?
+
+**A4**: No. Badmaths only supports 2D matrix in the calculation.
+
+**Q5**: In the matrix calculation, can I declare 1D matrix?
+
+**A5**: No. Badmaths only supports 2D matrix in the calculation. But you can treat 2D matrix with the single row as 1D matrix.
+If you declare matrix like `[1, 2, 3]`, the program would recognize it as 2D matrix with shape of `1 * 3`.
+
+**Q6**: In the matrix calculation, can I use multiple operators in single expression like `Matrix [1,2;3,4] + [1,2;3,4] + [1,2;3,4]`?
-**A**: {your answer here}
+**A6**: No. Only single operator should be contained in the single expression with two operands.
## Command Summary
-{Give a 'cheat sheet' of commands here}
+### General
+```
+History
+```
+```
+Help
+```
+```
+Bye
+```
+### Notes
+```
+Store isNote
+```
+```
+List
+```
+```
+List 2
+```
+```
+Delete 2
+```
+```
+Clear
+```
+```
+Mark 2
+```
+```
+Unmark 2
+```
+```
+FindMark
+```
+```
+FindUnmark
+```
+```
+FindInfo Add
+```
+```
+High 1
+```
+```
+Medium 1
+```
+```
+Low 1
+```
+```
+Rank Priority
+```
+```
+Rank Review Count
+```
+```
+FindPrior HIGH
+```
+```
+FindPrior MEDIUM
+```
+```
+FindPrior LOW
+```
+### Graph
+ ```
+ Graph 2*tan(2*pi*x+5)
+ ```
+ ```
+ Graph sin(1*x)
+ ```
+ ```
+ Graph 2*cos(1*x-6)-100
+ ```
+### Quadratic
+````
+Quadratic 2x^2 + x - 5
+````
+````
+Quadratic -x^2 - x + 2.5
+````
-* Add todo `todo n/TODO_NAME d/DEADLINE`
+### Matrix
+```
+Matrix [1,2;3,4] .* [1,2;3,4]
+```
+```
+Matrix [1,2;3,4] .* [1,2;3,4].T
+```
+```
+Matrix [1,2;3,4] * [1,2;3,4]
+```
+```
+Matrix [1,2;3,4] + [1,2;3,4]
+```
+```
+Matrix [1,2;3,4] - [1,2;3,4]
+```
diff --git a/docs/team/0nandon.md b/docs/team/0nandon.md
new file mode 100644
index 0000000000..6e4c1ccea5
--- /dev/null
+++ b/docs/team/0nandon.md
@@ -0,0 +1,61 @@
+# 🧑🏻💻 Seungjun Lee, Project Portfolio Page
+
+## 🤖 Project BadMaths
+
+BadMaths is a study tool focusing on mathematical help and note-taking. It supports
+a number of mathematical functions, including trigonemetric graphs, quadratic equations, and matrix calculations.
+
+## 👊🏻 Summary of Contributions
+
+### Code contributed
+
+My code contribution can be mainly separated with two parts:
+
+ * Source code for the matrix calculation and possible exceptions
+ * JUnit test codes for the matrix calculation
+
+If you want to see my code contributions more specifically, click [[here]](https://nus-cs2113-ay2223s2.github.io/tp-dashboard/?search=0nandon&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByAuthors&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2023-02-17&tabOpen=true&tabType=authorship&tabAuthor=0nandon&tabRepo=AY2223S2-CS2113-F10-2%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false).
+
+### Features added
+
+- Added a feature to support various matrix calculation. This allows users to input matrix equation and BadMaths
+ would be able to output the answer. BadMaths supports four operations below:
+
+ 1. Matrix multiplication
+ 2. Matrix element wise product
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix transpose
+
+### Enhancements added
+
+- Added JUnit tests for the `Calculate`, `Parser`, `Execute` classes.
+- Improve code more defensive with handling various possible exceptions:
+- Refined the code to be more OOP with following [[code standard]](https://se-education.org/guides/conventions/java/basic.html).
+- Added comments with `JavaDoc` style for the readability.
+- Added `logging`, `assert` statement for making debugging more easily.
+
+### Contributions to the UG
+
+- Contributed the section explaining the usage of the Matrix calculation.
+- Added various examples for the matrix calculation and expected output.
+- Added various examples for common mistakes that users can possibly do.
+- Added several cautions for the appropriate usage of the matrix calculation.
+- Added `FAQ` for the matrix calculation.
+- Added `Command Summary` for the matrix calculation.
+- Refined the whole contents of the UG for the readability.
+
+### Contributions to the DG
+
+- Contributed to the section detailing the functionality of the matrix calculation.
+- Created a `sequence diagram` to further explain how matrix calculation is conducted.
+- Created a `class diagram` to further explain relationships between classes for the matrix part.
+- Refined the whole contents of the DG for the readability.
+
+### Contributions to team-based tasks
+
+- Contributed to brainstorming of ideas and feature generation.
+- Tracked v1.0, v2.0, v2.1 milestones.
+- Provided basic coding advice and code quality checking assistance to group members.
+- Reviewed Pull Requests with assistance before merging them into the master branch on Github.
+- Manually tested jar file with checking whether there is any error.
diff --git a/docs/team/johndoe.md b/docs/team/johndoe.md
deleted file mode 100644
index ab75b391b8..0000000000
--- a/docs/team/johndoe.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# John Doe - Project Portfolio Page
-
-## Overview
-
-
-### Summary of Contributions
diff --git a/docs/team/khooyourun.md b/docs/team/khooyourun.md
new file mode 100644
index 0000000000..8485f3be89
--- /dev/null
+++ b/docs/team/khooyourun.md
@@ -0,0 +1,51 @@
+# Khoo You Run - Project Portfolio Page
+
+## Project BadMaths
+
+BadMaths is a study tool focusing on mathematical help and note-taking. Provides features to aid in solving questions
+revolving around matrices, quadratic equations, and trigonometric graphs.
+
+## Summary of Contributions
+
+### Code contributed
+[Here are my code contributions](https://nus-cs2113-ay2223s2.github.io/tp-dashboard/?search=khooyourun&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2023-02-17&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other&tabOpen=true&tabType=authorship&tabAuthor=khooyourun&tabRepo=AY2223S2-CS2113-F10-2%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false)
+
+### General functionalities implemented
+
+- Created and implemented the initial `BadMaths` class, `Command` class and `Parser` class that helped to facilitate the general
+flow of the program. BadMaths class took in user input, Parser class made sense of the user input and Command class executed
+the desired features. All the included features in BadMaths depend and run on these 3 classes.
+
+### Features added
+
+- Added a feature to solve quadratic equations. This allows users to input any quadratic equation and BadMaths would be
+able to output the answer. If the answer is imaginary, BadMaths would tell the user as such. BadMaths would also find the
+minimum or maximum point of the quadratic graph.
+
+### Enhancements added
+
+- Added JUnit Tests to `Quadratic`, `QuadraticParser` and `Parser`.
+- Made the code more OOP and improved readability.
+- Enhanced code defence by protecting it against bugs and possible exceptions.
+
+### Contributions to the UG
+
+- Contributed the Table of Contents for easy access to various sections of the UG.
+- Contributed the section explaining the usage of the Quadratic solver feature.
+- Contributed to the FAQ section.
+
+### Contributions to the DG
+
+- Created the Architecture Diagram.
+- Contributed to the section detailing the handling of User Input.
+- Contributed to the section detailing the functionality of the Quadratic solver.
+- Created a sequence diagram to further explain how Quadratic Solver works.
+- Added User Stories.
+- Added instructions for manual testing.
+
+### Contributions to team-based tasks / Review contributions
+
+- Contributed to brainstorming of ideas and feature generation.
+- Tracked v1.0, v2.0 milestones.
+- Helped group members with code quality checking and general coding advice.
+- Helped to review Pull Requests before merging into master branch on Github.
diff --git a/docs/team/wilsonlee2000.md b/docs/team/wilsonlee2000.md
new file mode 100644
index 0000000000..ddef350237
--- /dev/null
+++ b/docs/team/wilsonlee2000.md
@@ -0,0 +1,54 @@
+# Wilson Lee Jun Wei (Project Portfolio Page)
+
+## About Me
+Hello there!
+I am a second year student studying Computer Engineering, with a minor in Interactive Media Development at the National University Of Singapore.
+If you have any enquiries, feel free to reach out to me at wilsonleejunwei@u.nus.edu
+
+## Product Overview - BadMaths
+BadMaths is a Mathematical Study Tool that aims to help users to perform Mathematical Operations
+effectively and efficiently and contains various functionalities for note-taking
+
+## Summary of Contributions
+### 1) Code Contributed:
+Click [here](https://nus-cs2113-ay2223s2.github.io/tp-dashboard/?search=WilsonLee&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByAuthors&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2023-02-17&tabOpen=true&tabType=authorship&zFR=false&tabAuthor=WilsonLee2000&tabRepo=AY2223S2-CS2113-F10-2%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false)
+to view my codes contributed for this project
+
+### 2) Enhancements Implemented:
+* Added `Store` Feature for notes taking
+* Added `List` Feature for displaying items stored in notes
+* Added `Delete` Feature for removing items stored in notes
+* Added `History` Feature for displaying a list of all commands input by users
+* Refactoring codes as classes for `Store`, `List`, `Delete` and `CommandHistory`
+* Implemented JUnit Tests for `Store`, `List`, `Delete` and `CommandHistory`
+* Added details and improvements towards `HelpManual.txt`
+* Improve codes to more OOP
+
+### 3) UserGuide Contributions:
+* Contributed to overall formatting of UserGuide
+* Contributed to documentation for `Store`, `List`, `Delete`, `Clear`, `Mark`, `Unmark`,
+`FindMark`, `FindUnmark`, `FindInfo`, `FindPrior`, `History`, `Help`, `Bye`
+* Contributed to Command Summary for `Notes` and `General`
+
+### 4) DeveloperGuide Contributions:
+* Added Introduction
+* Added Table of Contents
+* Added Sequence Diagram for `Store`
+* Added Design & implementation details for `Store` class
+* Added Design & implementation details for `Delete` class
+* Added Design & implementation details for `Command` class
+* Added Design & implementation details for `List` class
+* Added Design & implementation details for `CommandHistory` class
+* Added Design & implementation details for `Ui` class
+* Added Design & implementation details for `notes.txt` file
+
+### 5) Contributions to team-based tasks:
+* Tracked `v1.0`, `v2.0`, and `v2.1` milestones
+* Assist in reviewing and approving team members' Pull Requests before merging to team's master branch
+* Contributed to team's brainstorming and discussion of ideas and features for BadMaths
+* Management of issues created on GitHub
+* Contributed to team's Google documents and Google sheet for BadMaths implementation
+* Helped team members in understanding GitHub properties such as `push` and `pull`
+
+### 6) Review / Mentoring Contributions:
+* Link to PRs reviewed [here](https://github.com/AY2223S2-CS2113-F10-2/tp/pulls?q=is%3Apr+reviewed-by%3AWilsonLee2000)
diff --git a/docs/team/yc-michael.md b/docs/team/yc-michael.md
new file mode 100644
index 0000000000..b422b05496
--- /dev/null
+++ b/docs/team/yc-michael.md
@@ -0,0 +1,36 @@
+# Hui Yu Cong - project Portfolio Page
+
+## Overview of product: BadMaths
+
+BadMaths is an integrated study tool that performs Mathematical Operations and contains
+various features for note-taking.
+
+## Summary of Contributions
+
+### Code contributed
+[My code contributions](https://nus-cs2113-ay2223s2.github.io/tp-dashboard/?search=&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2023-02-17&tabOpen=true&tabType=authorship&tabAuthor=YC-Michael&tabRepo=AY2223S2-CS2113-F10-2%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false)
+
+### Enhancements implemented
+
+- Created the Ui class to print outputs to the user
+- Added a feature that analyses basic trigonometry signals
+- Enhance the stated feature by visualising it using JFrame
+- Make the code more OOP and bug free
+- Added JUnit tests for TrigoGraph, TrigoGraphAnalyser and TrigoGraphVisualiser
+
+### Contributions to the UG
+
+- Contributed to `Feature 1: Graph Analyser and Visualiser`
+- Contributed to Graph portion of `Command Summary`
+
+### Contributions to the DG
+
+- Contributed to `Graph`
+- Added UML diagrams for `TrigoGraph class`
+
+### Contributions to team-based tasks / Review contributions
+
+- Created team organisation and tracked the progress of milestones v1.0, v2.0 and v2.1
+- Provided ideas for extra features (Review Count to track the number of times a user has viewed that particular note)
+- Assisted members in debugging their code offline
+- [PRs reviewed](https://github.com/AY2223S2-CS2113-F10-2/tp/pulls?q=is%3Apr+reviewed-by%3AYC-Michael)
diff --git a/docs/team/ziqiuzeng.md b/docs/team/ziqiuzeng.md
new file mode 100644
index 0000000000..cfb944b174
--- /dev/null
+++ b/docs/team/ziqiuzeng.md
@@ -0,0 +1,46 @@
+# ZENG ZIQIU's Project Portfolio Page
+## Project: BadMaths
+BadMaths is an integrated study tool that performs Mathematical Operations and contains various features for note-taking.
+## Summary of Contribution
+Given below are my contributions to the project:
+- Code Contributed: [RepoSense Link](https://nus-cs2113-ay2223s2.github.io/tp-dashboard/?search=ziqiuzeng&breakdown=true)
+- New Features:
+ - Added the ability to detect file corruption when launching program
+ - Added `Help` feature to display Help Manual of BadMaths
+ - Added the ability to modify the priority of notes
+ - Added the ability to find notes by `keyword`, `priority`, `status`
+ - Added the ability to `mark`/`unmark` note
+ - Added the ability to `Rank` all notes by `Priority`/`Review Count`
+ - Added the ability to `clear` all notes
+- Enhancements:
+ - Added JUnit Test for `NotesFileParser`, `NotesFileWriter`, `NotesFileContentManager`, and `NotesFileCleaner`
+ - Added JUnit Test for `NoteParser` and `InvalidNotesFileHandler`
+ - Added JUnit Test for `HelpManual`
+ - Added JUnit Test for `IndexChecker` and `IntegerChecker`
+ - Refactor `Storage` class and `executeCommand()` method
+ - Make the code more OOP
+- Project Management
+ - Managed Release [v2.0](https://github.com/AY2223S2-CS2113-F10-2/tp/releases/tag/v2.0)
+ - Tracked `v1.0`, `v2.0`, and `v2.1` milestones
+ - Managed issues via GitHub
+ - Manage team documentations:
+[Group Ideas](https://docs.google.com/document/d/1BfeY-7amQIlLvMt-YgQhyi-jJRB1y6goONhYVx2_tj8/edit),
+[User Story](https://docs.google.com/spreadsheets/d/1JSthry8kPJip282RwAYTB0ApbxfOQCNXWcnRzuLhJNI/edit#gid=0),
+[Draft UG](https://docs.google.com/document/d/1PGL8eMsa442esYVmjpDL4k8mMSnMI010kLE77_K-1T0/edit)
+- Documentation:
+ - User Guide:
+ - Added documentation for `Note` features
+ - Added documentation for the feature `Help`
+ - Contributed to the `FAQ` section
+ - Developer's Guide:
+ - Added format details of the `notes.txt` file
+ - Added sequence diagram of `NotesFileParser`
+ - Added implementation details of `Help`, `Storage`, and `Note`
+- Community
+ - [PR reviewed](https://github.com/AY2223S2-CS2113-F10-2/tp/issues?q=reviewed-by%3AZiqiuZeng)
+ - Contributed to brainstorming of ideas and features
+ - Provided ideas for `Command History` to keep track of previous commands
+ - Help teammates with basic feature implementation ideas and general code quality advice
+ - Help teammates with code testing and debugging
+ - Reported bugs and suggestions for other team in the class [PED](https://github.com/ZiqiuZeng/ped/issues)
+
diff --git a/src/main/java/seedu/badmaths/BadMaths.java b/src/main/java/seedu/badmaths/BadMaths.java
new file mode 100644
index 0000000000..d8ffa547b8
--- /dev/null
+++ b/src/main/java/seedu/badmaths/BadMaths.java
@@ -0,0 +1,86 @@
+package seedu.badmaths;
+
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.storage.NotesFileParser;
+import seedu.badmaths.ui.Ui;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Arrays;
+import java.util.Scanner;
+import java.io.File;
+import java.io.IOException;
+
+public class BadMaths {
+ private static final String path = "data/notes.txt";
+
+ private static final Set VALID_COMMANDS = new HashSet<>(Arrays.asList(
+ "Graph", "Bye", "List", "Store", "Matrix", "Help", "FindInfo", "FindPrior", "FindMark", "FindUnmark", "Low",
+ "Medium", "High", "Delete", "Mark", "Unmark", "Clear", "Rank", "Quadratic", "History"
+ ));
+
+ /**
+ * Checks whether command is one of the valid commands
+ * Throws exception if not
+ * @param command which is the user inputted command
+ */
+ public static void commandChecker(String command) {
+ try {
+ if (!VALID_COMMANDS.contains(command)) {
+ throw new IllegalArgumentException();
+ }
+ } catch (IllegalArgumentException e) {
+ Ui.printIncorrectFormatEntered();
+ }
+ }
+
+ public static void notesCreator(String path) {
+ File notesFile = new File(path);
+ if (!notesFile.exists()) {
+ if (!notesFile.getParentFile().exists()) {
+ notesFile.getParentFile().mkdirs();
+ }
+ try {
+ notesFile.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ Command inputCommand = null;
+ Ui.printWelcomeMessage();
+ notesCreator(path);
+ NotesList notes = new NotesList(NotesFileParser.loadFile(path));
+ ArrayList historyCommand = new ArrayList<>();
+ CommandHistory commandHist = new CommandHistory(historyCommand);
+
+ while (true) {
+ Scanner scanner = new Scanner(System.in);
+ String userInput = scanner.nextLine();
+
+ Parser parser = new Parser(userInput);
+ String command = parser.getCommand();
+ String toDo = parser.getToDo();
+ commandHist.storeCommand(userInput);
+
+ commandChecker(command);
+
+ if (inputCommand == null) {
+ inputCommand = new Command(command, toDo);
+ } else {
+ inputCommand.setCommand(command);
+ assert inputCommand.getCommand().equals(command) : "inputCommand != command";
+ inputCommand.setToDo(toDo);
+ }
+
+ inputCommand.executeCommand(notes, historyCommand);
+ if (userInput.equals("Bye")) {
+ System.exit(0);
+ }
+ }
+ }
+}
+
diff --git a/src/main/java/seedu/badmaths/Command.java b/src/main/java/seedu/badmaths/Command.java
new file mode 100644
index 0000000000..993d3ae7d3
--- /dev/null
+++ b/src/main/java/seedu/badmaths/Command.java
@@ -0,0 +1,174 @@
+/**
+ * Takes in function and command
+ * Identifies the function called and executes the appropriate function class
+ *
+ * @param command
+ * @param toDo
+ */
+
+package seedu.badmaths;
+import seedu.badmaths.commands.NotesRanker;
+import seedu.badmaths.commands.NotesFinder;
+import seedu.badmaths.commands.NotesPriorityFinder;
+import seedu.badmaths.commands.PrioritySetter;
+import seedu.badmaths.commands.NotesMarker;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.storage.NotesFileCleaner;
+import seedu.badmaths.trigograph.TrigoGraph;
+import seedu.badmaths.ui.Ui;
+import seedu.badmaths.matrix.Calculator;
+import seedu.badmaths.Quadratic.Quadratic;
+import java.util.ArrayList;
+
+
+public class Command {
+
+ private static final String filePath = "data/notes.txt";
+ protected String command;
+ protected String toDo;
+ ArrayList historyCommand = new ArrayList<>();
+
+ public Command(String command, String toDo) {
+ this.command = command;
+ this.toDo = toDo;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public void setCommand(String command) {
+ try {
+ this.command = command;
+ } catch (IllegalArgumentException e) {
+ Ui.printIncorrectFormatEntered();
+ }
+ }
+
+ public void setToDo(String toDo){
+ this.toDo = toDo;
+ }
+
+ public boolean isInvalidTodo(String todo) {
+ return todo.equals("Invalid todo");
+ }
+
+ public void executeCommand(NotesList notes, ArrayList historyCommand) {
+ TrigoGraph trigoGraph = new TrigoGraph(toDo);
+ Calculator calculator = new Calculator();
+ Quadratic quadratic = new Quadratic(toDo);
+ CommandHistory commandHist = new CommandHistory(historyCommand);
+ NotesMarker notesMarker = new NotesMarker(notes, filePath);
+ PrioritySetter prioritySetter = new PrioritySetter(notes, filePath);
+ NotesFinder notesFinder = new NotesFinder(notes, filePath);
+ NotesPriorityFinder notesPriorityFinder = new NotesPriorityFinder(notes, filePath);
+ NotesRanker notesRanker = new NotesRanker(notes, filePath);
+ try {
+ //@@author WilsonLee2000
+ assert (command.equals("Bye") || command.equals("Graph") || command.equals("Store") ||
+ command.equals("List") || command.equals("Delete") || command.equals("Mark") ||
+ command.equals("Unmark") || command.equals("Low") || command.equals("Medium") ||
+ command.equals("High") || command.equals("FindInfo") || command.equals("FindPrior") ||
+ command.equals("FindMark") || command.equals("FindUnmark") || command.equals("Rank") ||
+ command.equals("Clear") || command.equals("Help") || command.equals("Matrix") ||
+ command.equals("Quadratic") || command.equals("History")) : "input has incorrect format required";
+ //@@author Khooyourun
+ switch (command) {
+ case "Bye":
+ if(!isInvalidTodo(toDo)) {
+ throw new IllegalTodoException();
+ }
+ System.out.println("Goodbye!");
+ break;
+ case "Graph":
+ trigoGraph.startGraphAnalysis();
+ break;
+ //@@author WilsonLee2000
+ case "Store":
+ Store store = new Store(notes, toDo);
+ store.storeNotes();
+ break;
+ //@@author WilsonLee2000
+ case "List":
+ List lists = new List(notes, toDo);
+ lists.listNotes();
+ break;
+ //@@author WilsonLee2000
+ case "Delete":
+ Delete deletes = new Delete(notes, toDo);
+ deletes.deleteNotes();
+ break;
+ //@@author WilsonLee2000
+ case "History":
+ commandHist.displayHistory();
+ break;
+ //@@author ZiqiuZeng
+ case "Mark":
+ notesMarker.mark(toDo);
+ break;
+ //@@author ZiqiuZeng
+ case "Unmark":
+ notesMarker.unmark(toDo);
+ break;
+ //@@author ZiqiuZeng
+ case "Low":
+ case "Medium":
+ case "High":
+ prioritySetter.setPriority(command,toDo);
+ break;
+ //@@author ZiqiuZeng
+ case "FindInfo":
+ notesFinder.find(toDo);
+ break;
+ //@@author ZiqiuZeng
+ case "FindPrior":
+ notesPriorityFinder.find(toDo);
+ break;
+ //@@author ZiqiuZeng
+ case "FindMark":
+ Ui.printFindNotes(notes.relevantMarked());
+ break;
+ //@@author ZiqiuZeng
+ case "FindUnmark":
+ Ui.printFindNotes(notes.relevantUnmarked());
+ break;
+ //@@author ZiqiuZeng
+ case "Rank":
+ notesRanker.rank(toDo);
+ break;
+ /*
+ * The command "Clear" will continue to execute for as long as it is being entered,
+ * without any other command or input interrupting it.
+ */
+ case "Clear":
+ notes.reset();
+ NotesFileCleaner.clearFile(filePath);
+ break;
+ /*
+ * The command "Help" will continue to execute for as long as it is being entered,
+ * without any other command or input interrupting it.
+ */
+ case "Help":
+ HelpManual.readHelpManual();
+ break;
+ //@@author 0nandon
+ case "Matrix":
+ calculator.run(toDo);
+ break;
+ //@@author Khooyourun
+ case "Quadratic":
+ quadratic.solveQuadratic();
+ break;
+ default:
+ break;
+ }
+ } catch (IllegalIndexException e) {
+ System.out.println("Oops! This note does not exist. Please try again.");
+ } catch (IllegalTodoException e) {
+ Ui.printIncorrectFormatEntered();
+ }
+
+ Ui.printLineBreak();
+ }
+}
+
diff --git a/src/main/java/seedu/badmaths/CommandHistory.java b/src/main/java/seedu/badmaths/CommandHistory.java
new file mode 100644
index 0000000000..d17fee29b5
--- /dev/null
+++ b/src/main/java/seedu/badmaths/CommandHistory.java
@@ -0,0 +1,33 @@
+//@@author WilsonLee2000
+
+/**
+ * Takes in an ArrayList containing previous history commands that the user have entered so far
+ * during the current programme run session.
+ * Prints out a list of history commands from the ArrayList if function is called.
+ *
+ * @param historyCommand
+ */
+
+package seedu.badmaths;
+import java.util.ArrayList;
+
+public class CommandHistory {
+
+ ArrayList historyCommand = new ArrayList<>();
+
+ public CommandHistory(ArrayList historyCommand) {
+ this.historyCommand = historyCommand;
+ }
+
+ public void storeCommand(String inputCommand) {
+ historyCommand.add(inputCommand);
+ }
+
+ public void displayHistory() {
+ System.out.println("Here are the list of commands that you have entered so far:");
+ for (String command : historyCommand) {
+ System.out.println(command);
+ }
+ System.out.println();
+ }
+}
diff --git a/src/main/java/seedu/badmaths/Delete.java b/src/main/java/seedu/badmaths/Delete.java
new file mode 100644
index 0000000000..f5c73847f1
--- /dev/null
+++ b/src/main/java/seedu/badmaths/Delete.java
@@ -0,0 +1,59 @@
+//@@author WilsonLee2000
+
+/**
+ * Takes in an index that is being input by users.
+ * Deletes an item from the notes based on the index that is being provided by users.
+ *
+ * @param notes
+ * @param toDo
+ */
+
+package seedu.badmaths;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.storage.NotesFileWriter;
+import seedu.badmaths.ui.Ui;
+
+public class Delete {
+
+ private static final String filePath = "data/notes.txt";
+ public NotesList notes;
+ protected String toDo;
+
+ public Delete (NotesList notes, String toDo) {
+ this.toDo = toDo;
+ this.notes = notes;
+ }
+
+ public static boolean isInvalidIndex(int index, NotesList notes) {
+ return (index < 0 || index >= notes.getSize());
+ }
+
+ public static boolean isAnInt(String todo) {
+ try {
+ Integer.parseInt(todo);
+ } catch (NumberFormatException numberException) {
+ Ui.printInvalidNumberEntered();
+ return false;
+ }
+ return true;
+ }
+
+ public void deleteNotes() {
+ try {
+ if (!isAnInt(toDo)) {
+ throw new IllegalTodoException();
+ }
+ int deleteIndex = Integer.parseInt(toDo) - 1;
+ if (isInvalidIndex(deleteIndex, notes)) {
+ throw new IllegalIndexException();
+ }
+ Ui.printDelete(notes.getText(deleteIndex), notes.getSize());
+ notes.remove(deleteIndex);
+ NotesFileWriter.saveFile(filePath, notes.getAll());
+ } catch (IllegalIndexException exceptionIndex) {
+ System.out.println("Oops! This note does not exist. Please try again.");
+ } catch (IllegalTodoException exceptionTodo) {
+ Ui.printIncorrectFormatEntered();
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/HelpManual.java b/src/main/java/seedu/badmaths/HelpManual.java
new file mode 100644
index 0000000000..e51c6d4d65
--- /dev/null
+++ b/src/main/java/seedu/badmaths/HelpManual.java
@@ -0,0 +1,69 @@
+/**
+ * Provides the HelpManual to guide users who are operating BadMaths.
+ */
+
+package seedu.badmaths;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.InputStream;
+import java.io.BufferedReader;
+
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+
+public class HelpManual {
+ protected static String filePath = "/HelpManual.txt"; // file path relative to the classpath
+ protected static String logFilePath = "Help";
+ private static final Logger logger = Logger.getLogger(logFilePath);
+
+ public static void setUpLogger() {
+ LogManager.getLogManager().reset();
+ logger.setLevel(Level.ALL);
+ try {
+ if (!new File(logFilePath).exists()) {
+ new File(logFilePath).createNewFile();
+ }
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "File logger not working", e);
+ }
+ }
+
+ /**
+ * This method reads the content from HelpManual.txt file.
+ */
+ public static void readHelpManual() {
+ setUpLogger();
+ try {
+ logger.log(Level.INFO, "going to start processing");
+ InputStream inputStream = HelpManual.class.getResourceAsStream(filePath);
+
+ // assert that the input stream is not null
+ assert inputStream != null : "Invalid file: " + filePath;
+
+ InputStreamReader read = new InputStreamReader(inputStream, "UTF-8");
+ BufferedReader bufferedReader = new BufferedReader(read);
+
+ String lineTxt;
+ StringBuilder content = new StringBuilder();
+
+ while ((lineTxt = bufferedReader.readLine()) != null) {
+ content.append(lineTxt).append("\n");
+ System.out.println(lineTxt);
+ }
+ bufferedReader.close();
+ read.close();
+
+ // Log successful read to console and log file
+ logger.log(Level.INFO, "Successfully read Help Manual file.");
+
+ } catch (Exception e) {
+ System.out.println("Error while loading files. Please try again.");
+ logger.severe("Error while loading Help Manual. Please try again.");
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/IllegalIndexException.java b/src/main/java/seedu/badmaths/IllegalIndexException.java
new file mode 100644
index 0000000000..ff9daa906d
--- /dev/null
+++ b/src/main/java/seedu/badmaths/IllegalIndexException.java
@@ -0,0 +1,4 @@
+package seedu.badmaths;
+
+public class IllegalIndexException extends Exception{
+}
diff --git a/src/main/java/seedu/badmaths/IllegalTodoException.java b/src/main/java/seedu/badmaths/IllegalTodoException.java
new file mode 100644
index 0000000000..4d7953d889
--- /dev/null
+++ b/src/main/java/seedu/badmaths/IllegalTodoException.java
@@ -0,0 +1,4 @@
+package seedu.badmaths;
+
+public class IllegalTodoException extends Exception{
+}
diff --git a/src/main/java/seedu/badmaths/InvalidFormatException.java b/src/main/java/seedu/badmaths/InvalidFormatException.java
new file mode 100644
index 0000000000..2850184d69
--- /dev/null
+++ b/src/main/java/seedu/badmaths/InvalidFormatException.java
@@ -0,0 +1,4 @@
+package seedu.badmaths;
+
+public class InvalidFormatException extends Throwable {
+}
diff --git a/src/main/java/seedu/badmaths/List.java b/src/main/java/seedu/badmaths/List.java
new file mode 100644
index 0000000000..b770543693
--- /dev/null
+++ b/src/main/java/seedu/badmaths/List.java
@@ -0,0 +1,66 @@
+//@@author WilsonLee2000
+
+/**
+ * Takes in an index that is being input by users, for displaying of items from notes list.
+ * Prints out an item from the notes based on the index that is being provided by users.
+ * Alternatively, if index is not provided by users, prints out a list of all items from the notes.
+ *
+ * @param notes
+ * @param toDo
+ */
+
+package seedu.badmaths;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.ui.Ui;
+
+public class List {
+
+ public NotesList notes;
+ protected String toDo;
+
+ public List(NotesList notes, String toDo) {
+ this.notes = notes;
+ this.toDo = toDo;
+ }
+
+ public boolean isInvalidIndex(int index, NotesList notes) {
+ return (index < 0 || index >= notes.getSize());
+ }
+
+ public boolean isInvalidTodo(String todo) {
+ return todo.equals("Invalid todo");
+ }
+
+ public boolean isAnInt(String todo) {
+ try {
+ Integer.parseInt(todo);
+ } catch (NumberFormatException numberException) {
+ Ui.printInvalidNumberEntered();
+ return false;
+ }
+ return true;
+ }
+
+ public void listNotes() {
+ try {
+ if ((!isInvalidTodo(toDo)) && (!isAnInt(toDo))) {
+ throw new IllegalTodoException();
+ }
+ if (isInvalidTodo(toDo)) {
+ Ui.printNotes(notes.getAll());
+ return;
+ }
+ int index = Integer.parseInt(toDo) - 1;
+
+ if (isInvalidIndex(index, notes)) {
+ throw new IllegalIndexException();
+ }
+ notes.review(index);
+ Ui.printSpecificNote(index, notes.getAll());
+ } catch (IllegalIndexException exceptionIndex) {
+ System.out.println("Oops! This note does not exist. Please try again.");
+ } catch (IllegalTodoException exceptionTodo) {
+ Ui.printIncorrectFormatEntered();
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/Parser.java b/src/main/java/seedu/badmaths/Parser.java
new file mode 100644
index 0000000000..1690c1e849
--- /dev/null
+++ b/src/main/java/seedu/badmaths/Parser.java
@@ -0,0 +1,65 @@
+/**
+ * Takes in user input and splits it into 2 parts
+ * First part is the function name
+ * Second part is the todo to be executed in that function
+ * Returns the two parts using get methods
+ *
+ * @param userInput
+ */
+
+package seedu.badmaths;
+
+import seedu.badmaths.ui.Ui;
+
+public class Parser {
+
+ protected String userInput;
+
+ public Parser(String userInput) { // List. 1
+ this.userInput = userInput;
+ }
+
+ /**
+ * Separates the first word of user input which is the command
+ * Throws an exception if there is format error in the input
+ * @return command
+ */
+ public String getCommand() {
+ try {
+ String trimmedInput = userInput.trim();
+ if (trimmedInput.contains(" ")) {
+ int indexOfSpace = trimmedInput.indexOf(" ");
+ String command = trimmedInput.substring(0, indexOfSpace);
+ return command;
+ } else {
+ return userInput;
+ }
+ } catch (IllegalArgumentException e) {
+ Ui.printIncorrectFormatEntered();
+ return null;
+ }
+ }
+
+ /**
+ * Separates all the words other than the first from user input which would be toDo
+ * If there is only 1 word (ie no toDo), then "Invalid toDo" would be returned
+ * Throws an exception if there is format error
+ * @return toDo
+ */
+ public String getToDo() {
+ try {
+ String[] parts = userInput.trim().split(" ", 2);
+ if (parts.length == 1) {
+ return "Invalid todo"; // means there is no todo
+ } else {
+ return parts[1].trim();
+ }
+ } catch (IllegalArgumentException e) {
+ Ui.printIncorrectFormatEntered();
+ return null;
+ }
+ }
+}
+
+
+
diff --git a/src/main/java/seedu/badmaths/Quadratic/Quadratic.java b/src/main/java/seedu/badmaths/Quadratic/Quadratic.java
new file mode 100644
index 0000000000..ca17acd77e
--- /dev/null
+++ b/src/main/java/seedu/badmaths/Quadratic/Quadratic.java
@@ -0,0 +1,78 @@
+/**
+ * Takes in a quadratic equation and calculates the values of x
+ * Prints out the x values if real, and notifies user if its imaginary
+ *
+ * Contains a String toDo which is the quadratic equation
+ */
+
+package seedu.badmaths.Quadratic;
+import java.util.ArrayList;
+import seedu.badmaths.ui.Ui;
+
+public class Quadratic {
+
+ protected static String toDo;
+
+ public Quadratic (String toDo) {
+ Quadratic.toDo = toDo;
+ }
+
+ /**
+ * Solves the quadratic equation, Ax^2 + Bx + C, to get 2 values of x
+ * @param A which is the A value
+ * @param B which is the B value
+ * @param C which is the C value
+ * @return xStore which is an ArrayList of Doubles containing 2 elements, the two values of x
+ */
+ public ArrayList quadraticFormula(double A, double B, double C) {
+ double x1 = (-B + Math.sqrt(B * B - 4 * A * C)) / (2 * A);
+ double x2 = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A);
+ ArrayList xStore = new ArrayList<>();
+ xStore.add(x1);
+ xStore.add(x2);
+ return xStore;
+ }
+
+ /**
+ * Finds the coordinates of the minimum or maximum point of the quadratic equation, Ax^2 + Bx + C
+ * @param A which is the A value
+ * @param B which is the B value
+ * @param C which is the C value
+ * @return the coordinates in the form of a string: (x,y)
+ */
+ public String minMaxPointFinder(double A, double B, double C) {
+ double xCoordinate = (-B) / (2 * A);
+ double yCoordinate = (A * (xCoordinate * xCoordinate)) + (B * xCoordinate) + C;
+ String stringofXCoor = Double.toString(xCoordinate);
+ String stringOfYCoor = Double.toString(yCoordinate);
+ return "(" + stringofXCoor + (", ") + stringOfYCoor + ")";
+ }
+
+ public void printAnswer(ArrayList xStore, String vertextCoordinate, boolean isMinimum) {
+ Ui.printQuadraticAnswer(xStore, vertextCoordinate, isMinimum);
+ }
+
+ /**
+ * Calls the above methods to find and print the answer to the quadratic equation
+ * Catches possible exceptions and prints an error message
+ */
+ public void solveQuadratic() {
+ try {
+ double A = QuadraticParser.findA();
+ double B = QuadraticParser.findB();
+ double C = QuadraticParser.findC();
+ boolean isMinimum;
+ if (A > 0) {
+ isMinimum = true;
+ } else {
+ isMinimum = false;
+ }
+ ArrayList xStore;
+ xStore = quadraticFormula(A, B, C);
+ String vertexCoordinate = minMaxPointFinder(A, B, C);
+ printAnswer(xStore, vertexCoordinate, isMinimum);
+ } catch (NumberFormatException | IndexOutOfBoundsException e) {
+ Ui.printQuadraticFormatError();
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/Quadratic/QuadraticParser.java b/src/main/java/seedu/badmaths/Quadratic/QuadraticParser.java
new file mode 100644
index 0000000000..a7fdb01027
--- /dev/null
+++ b/src/main/java/seedu/badmaths/Quadratic/QuadraticParser.java
@@ -0,0 +1,102 @@
+package seedu.badmaths.Quadratic;
+
+public class QuadraticParser extends Quadratic {
+
+ private static final int POSITIVE = 1;
+ private static final int NEGATIVE = -1;
+ private static final String ADDITION = "+";
+ private static final String SUBTRACTION = "-";
+ private static final int INDEX_MODIFIER_2 = 2;
+ private static final int INDEX_MODIFIER_3 = 3;
+ private static final int INDEX_MODIFIER_4 = 4;
+ private static final int INDEX_MODIFIER_5 = 5;
+
+ public QuadraticParser(String toDo) {
+ super(toDo);
+ }
+
+ /**
+ * Identifies A from Ax^2 + Bx + C
+ * @return A as a double data type
+ */
+ public static double findA() {
+ String stringA = toDo.substring(0, toDo.indexOf("x"));
+ if (stringA.equals(SUBTRACTION)) {
+ return NEGATIVE;
+ } else {
+ if (stringA.isEmpty()) {
+ return POSITIVE;
+ } else {
+ return Double.parseDouble(stringA);
+ }
+ }
+ }
+
+ /**
+ * Identifies the sign of B (+ or -)
+ * @return the sign as a String
+ */
+ public static String findSignOfB() {
+ int startIndexOfSign = toDo.indexOf("^2") + INDEX_MODIFIER_3;
+ int endIndexOfSign = toDo.indexOf("^2") + INDEX_MODIFIER_4;
+ return toDo.substring(startIndexOfSign, endIndexOfSign);
+ }
+
+ public static String findStringOfB() {
+ int startIndexOfB = toDo.indexOf("^2") + INDEX_MODIFIER_5;
+ int endIndexOfB = toDo.indexOf("x ");
+ return toDo.substring(startIndexOfB, endIndexOfB);
+ }
+
+ /**
+ * Identifies B from Ax^2 + Bx + C
+ * @return A as a double data type
+ */
+ public static double findB() {
+ String sign = findSignOfB();
+ String stringB = findStringOfB();
+ if (stringB.isEmpty()) {
+ if (sign.equals(ADDITION)) {
+ return POSITIVE;
+ } else {
+ return NEGATIVE;
+ }
+ } else {
+ if (sign.equals(ADDITION)) {
+ return Double.parseDouble(stringB);
+ } else {
+ return Double.parseDouble(stringB) * NEGATIVE;
+ }
+ }
+ }
+
+ /**
+ * Identifies the sign of C (+ or -)
+ * @return the sign as a String
+ */
+ public static String findSignOfC() {
+ int startIndexOfSign = toDo.indexOf("x ") + INDEX_MODIFIER_2;
+ int endIndexOfSign = toDo.indexOf("x ") + INDEX_MODIFIER_3;
+ return toDo.substring(startIndexOfSign, endIndexOfSign);
+ }
+
+ public static String findStringOfC() {
+ int indexOfC = toDo.indexOf("x ") + INDEX_MODIFIER_4;
+ return toDo.substring(indexOfC);
+ }
+
+ /**
+ * Identifies C from Ax^2 + Bx + C
+ * @return C as a double data type
+ */
+ public static double findC() {
+ String sign = findSignOfC();
+ String stringC = findStringOfC();
+ double C = Double.parseDouble(stringC);
+ if (sign.equals(ADDITION)) {
+ return C;
+ } else {
+ return C * NEGATIVE;
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/Store.java b/src/main/java/seedu/badmaths/Store.java
new file mode 100644
index 0000000000..9580c0f6f7
--- /dev/null
+++ b/src/main/java/seedu/badmaths/Store.java
@@ -0,0 +1,46 @@
+//@@author WilsonLee2000
+
+/**
+ * Takes in a String toDo and stores the toDo String provided by users into the notes list.
+ *
+ * @param notes
+ * @param toDo
+ */
+
+package seedu.badmaths;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.storage.NotesFileWriter;
+import seedu.badmaths.ui.Ui;
+
+public class Store {
+
+ private static final String filePath = "data/notes.txt";
+ public NotesList notes;
+ protected String toDo;
+
+ public Store(NotesList notes, String toDo) {
+ this.toDo = toDo;
+ this.notes = notes;
+ }
+
+ public static boolean isInvalidTodo(String todo) {
+ return todo.equals("Invalid todo");
+ }
+
+ public void storeNotes() {
+ try {
+ if (isInvalidTodo(toDo)) {
+ throw new IllegalTodoException();
+ }
+ if (toDo.equals("null")) {
+ throw new IllegalTodoException();
+ }
+ notes.add(toDo);
+ Ui.printAddNote(toDo, notes.getSize());
+ NotesFileWriter.saveFile(filePath, notes.getAll());
+ } catch (IllegalTodoException exception) {
+ Ui.printIncorrectFormatEntered();
+ }
+ }
+}
+
diff --git a/src/main/java/seedu/badmaths/commands/IndexChecker.java b/src/main/java/seedu/badmaths/commands/IndexChecker.java
new file mode 100644
index 0000000000..83b18c8327
--- /dev/null
+++ b/src/main/java/seedu/badmaths/commands/IndexChecker.java
@@ -0,0 +1,9 @@
+package seedu.badmaths.commands;
+
+import seedu.badmaths.note.NotesList;
+
+public class IndexChecker {
+ public static boolean isInvalidIndex(int index, NotesList notes) {
+ return index < 0 || index >= notes.getSize();
+ }
+}
diff --git a/src/main/java/seedu/badmaths/commands/IntegerChecker.java b/src/main/java/seedu/badmaths/commands/IntegerChecker.java
new file mode 100644
index 0000000000..eb6150a714
--- /dev/null
+++ b/src/main/java/seedu/badmaths/commands/IntegerChecker.java
@@ -0,0 +1,15 @@
+package seedu.badmaths.commands;
+
+import seedu.badmaths.ui.Ui;
+
+public class IntegerChecker {
+ public static boolean isAnInt(String str) {
+ try {
+ Integer.parseInt(str);
+ return true;
+ } catch (NumberFormatException e) {
+ Ui.printInvalidNumberEntered();
+ return false;
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/commands/NotesFinder.java b/src/main/java/seedu/badmaths/commands/NotesFinder.java
new file mode 100644
index 0000000000..23abe6b228
--- /dev/null
+++ b/src/main/java/seedu/badmaths/commands/NotesFinder.java
@@ -0,0 +1,29 @@
+package seedu.badmaths.commands;
+
+import seedu.badmaths.IllegalTodoException;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.ui.Ui;
+
+import java.util.ArrayList;
+
+import static seedu.badmaths.Store.isInvalidTodo;
+
+public class NotesFinder {
+ private NotesList notes;
+ private String filePath;
+
+ public NotesFinder(NotesList notes, String filePath) {
+ this.notes = notes;
+ this.filePath = filePath;
+ }
+
+ public void find(String keyword) throws IllegalTodoException {
+ if (isInvalidTodo(keyword)) {
+ throw new IllegalTodoException();
+ }
+
+ ArrayList relevantNotes = notes.relevantInfo(keyword);
+ Ui.printFindNotes(relevantNotes);
+ }
+}
diff --git a/src/main/java/seedu/badmaths/commands/NotesMarker.java b/src/main/java/seedu/badmaths/commands/NotesMarker.java
new file mode 100644
index 0000000000..a6788d15d9
--- /dev/null
+++ b/src/main/java/seedu/badmaths/commands/NotesMarker.java
@@ -0,0 +1,50 @@
+package seedu.badmaths.commands;
+
+import seedu.badmaths.IllegalIndexException;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.storage.NotesFileWriter;
+import seedu.badmaths.ui.Ui;
+
+import static seedu.badmaths.commands.IntegerChecker.isAnInt;
+import static seedu.badmaths.commands.IndexChecker.isInvalidIndex;
+
+public class NotesMarker {
+ private NotesList notes;
+ private String filePath;
+
+ public NotesMarker(NotesList notes, String filePath) {
+ this.notes = notes;
+ this.filePath = filePath;
+ }
+
+ public void mark(String toDo) throws IllegalIndexException {
+ if (!isAnInt(toDo)) {
+ return;
+ }
+
+ int markIndex = Integer.parseInt(toDo) - 1;
+ if (isInvalidIndex(markIndex, notes)) {
+ throw new IllegalIndexException();
+ }
+
+ notes.markAsDone(markIndex);
+ Ui.printMark(notes.getText(markIndex));
+ NotesFileWriter.saveFile(filePath, notes.getAll());
+ }
+
+ public void unmark(String toDo) throws IllegalIndexException {
+ if (!isAnInt(toDo)) {
+ return;
+ }
+
+ int unmarkIndex = Integer.parseInt(toDo) - 1;
+ if (isInvalidIndex(unmarkIndex, notes)) {
+ throw new IllegalIndexException();
+ }
+
+ notes.markAsUndone(unmarkIndex);
+ Ui.printUnmark(notes.getText(unmarkIndex));
+ NotesFileWriter.saveFile(filePath, notes.getAll());
+ }
+
+}
diff --git a/src/main/java/seedu/badmaths/commands/NotesPriorityFinder.java b/src/main/java/seedu/badmaths/commands/NotesPriorityFinder.java
new file mode 100644
index 0000000000..53b7a2a9ac
--- /dev/null
+++ b/src/main/java/seedu/badmaths/commands/NotesPriorityFinder.java
@@ -0,0 +1,31 @@
+package seedu.badmaths.commands;
+
+import seedu.badmaths.IllegalTodoException;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.ui.Ui;
+
+import java.util.ArrayList;
+
+public class NotesPriorityFinder {
+ private NotesList notes;
+ private String filePath;
+
+ public NotesPriorityFinder(NotesList notes, String filePath) {
+ this.notes = notes;
+ this.filePath = filePath;
+ }
+
+ public void find(String priorityStr) throws IllegalTodoException{
+ switch (priorityStr.toLowerCase()) {
+ case "low":
+ case "medium":
+ case "high":
+ ArrayList relevantNotes = notes.relevantPriority(priorityStr.toUpperCase());
+ Ui.printFindNotes(relevantNotes);
+ break;
+ default:
+ throw new IllegalTodoException();
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/commands/NotesRanker.java b/src/main/java/seedu/badmaths/commands/NotesRanker.java
new file mode 100644
index 0000000000..edf99b31a8
--- /dev/null
+++ b/src/main/java/seedu/badmaths/commands/NotesRanker.java
@@ -0,0 +1,34 @@
+package seedu.badmaths.commands;
+
+import seedu.badmaths.IllegalTodoException;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.storage.NotesFileWriter;
+import seedu.badmaths.ui.Ui;
+
+public class NotesRanker {
+ private NotesList notes;
+ private String filePath;
+
+ public NotesRanker(NotesList notes, String filePath) {
+ this.notes = notes;
+ this.filePath = filePath;
+ }
+
+ public void rank(String toDo) throws IllegalTodoException {
+ switch (toDo) {
+ case "Review Count":
+ notes.rankByReviewCount();
+ Ui.printNotesByReviewCount(notes.getAll());
+ NotesFileWriter.saveFile(filePath, notes.getAll());
+ break;
+ case "Priority":
+ notes.rankByPriority();
+ Ui.printNotesByPriority(notes.getAll());
+ NotesFileWriter.saveFile(filePath, notes.getAll());
+ break;
+ default:
+ throw new IllegalTodoException();
+ }
+ }
+
+}
diff --git a/src/main/java/seedu/badmaths/commands/PrioritySetter.java b/src/main/java/seedu/badmaths/commands/PrioritySetter.java
new file mode 100644
index 0000000000..bdcc0b3d40
--- /dev/null
+++ b/src/main/java/seedu/badmaths/commands/PrioritySetter.java
@@ -0,0 +1,37 @@
+package seedu.badmaths.commands;
+
+import seedu.badmaths.IllegalIndexException;
+import seedu.badmaths.note.NotesList;
+import seedu.badmaths.note.NotePriority;
+import seedu.badmaths.storage.NotesFileWriter;
+import seedu.badmaths.ui.Ui;
+
+import static seedu.badmaths.commands.IntegerChecker.isAnInt;
+import static seedu.badmaths.commands.IndexChecker.isInvalidIndex;
+
+public class PrioritySetter {
+ private NotesList notes;
+ private String filePath;
+
+ public PrioritySetter(NotesList notes, String filePath) {
+ this.notes = notes;
+ this.filePath = filePath;
+ }
+
+ public void setPriority(String priorityString, String toDo) throws IllegalIndexException {
+ if (!isAnInt(toDo)) {
+ return;
+ }
+
+ int index = Integer.parseInt(toDo) - 1;
+ if (isInvalidIndex(index, notes)) {
+ throw new IllegalIndexException();
+ }
+
+ NotePriority.Priority priority = NotePriority.Priority.valueOf(priorityString.toUpperCase());
+
+ notes.setPriority(index, priority);
+ Ui.printPriority(index, notes.getAll());
+ NotesFileWriter.saveFile(filePath, notes.getAll());
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/Calculate.java b/src/main/java/seedu/badmaths/matrix/Calculate.java
new file mode 100644
index 0000000000..36a5f82c1c
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Calculate.java
@@ -0,0 +1,137 @@
+package seedu.badmaths.matrix;
+
+import seedu.badmaths.matrix.exception.ExceptionChecker;
+import seedu.badmaths.matrix.exception.ExceptionPrinter;
+import seedu.badmaths.matrix.exception.ShapeMismatchException;
+
+import java.util.logging.Logger;
+
+/**
+ * This class calculates the various matrix calculation below:
+ * 1. Matrix multiplication
+ * 2. Matrix element wise product
+ * 3. Matrix subtraction
+ * 4. Matrix addition
+ */
+public class Calculate {
+ ExceptionChecker check = new ExceptionChecker();
+ Logger logger = Logger.getLogger("Exception");
+ ExceptionPrinter ep = new ExceptionPrinter();
+
+ /**
+ * Calculate the matrix multiplication.
+ *
+ * @param t1 operand1
+ * @param t2 operand2
+ */
+ public Tensor2D mul(Tensor2D t1, Tensor2D t2) {
+ Shape t1Shape = t1.shape();
+ Shape t2Shape = t2.shape();
+
+ try{
+ check.checkShapeMismatch(t1, t2, "MUL");
+
+ Tensor2D t2T = t2.t();
+ int[][] output = new int[t1Shape.row][t2Shape.column];
+
+ for(int i = 0; i < t1Shape.row; i++) {
+ for(int j = 0; j < t2Shape.column; j++) {
+ output[i][j] = 0;
+
+ for(int k = 0; k < t1Shape.column; k++) {
+ output[i][j] += t1.get(i, k) * t2T.get(j, k);
+ }
+ }
+ }
+
+ return new Tensor2D(output);
+ } catch (ShapeMismatchException e) {
+ ep.printShapeMismatchExceptionLog();
+ return null;
+ }
+ }
+
+ /**
+ * Calculate the matrix element wise product.
+ *
+ * @param t1 operand1
+ * @param t2 operand2
+ */
+ public Tensor2D dot(Tensor2D t1, Tensor2D t2) {
+ Shape t1Shape = t1.shape();
+ Shape t2Shape = t2.shape();
+
+ try {
+ check.checkShapeMismatch(t1, t2, "DOT");
+
+ int[][] output = new int[t1Shape.row][t1Shape.column];
+
+ for(int i = 0; i < t1Shape.row; i++) {
+ for(int j = 0; j < t1Shape.column; j++) {
+ output[i][j] = t1.get(i, j) * t2.get(i, j);
+ }
+ }
+
+ return new Tensor2D(output);
+ } catch (ShapeMismatchException e) {
+ ep.printShapeMismatchExceptionLog();
+ return null;
+ }
+ }
+
+ /**
+ * Calculate the matrix addition.
+ *
+ * @param t1 operand1
+ * @param t2 operand2
+ */
+ public Tensor2D add(Tensor2D t1, Tensor2D t2) {
+ Shape t1Shape = t1.shape();
+ Shape t2Shape = t2.shape();
+
+ try {
+ check.checkShapeMismatch(t1, t2, "ADD");
+
+ int[][] output = new int[t1Shape.row][t1Shape.column];
+
+ for(int i = 0; i < t1Shape.row; i++) {
+ for(int j = 0; j < t1Shape.column; j++) {
+ output[i][j] = t1.get(i, j) + t2.get(i, j);
+ }
+ }
+
+ return new Tensor2D(output);
+ } catch (ShapeMismatchException e) {
+ ep.printShapeMismatchExceptionLog();
+ return null;
+ }
+ }
+
+ /**
+ * Calculate the matrix subtraction.
+ *
+ * @param t1 operand1
+ * @param t2 operand2
+ */
+ public Tensor2D sub(Tensor2D t1, Tensor2D t2) {
+ Shape t1Shape = t1.shape();
+ Shape t2Shape = t2.shape();
+
+ try {
+ check.checkShapeMismatch(t1, t2, "SUB");
+
+ int[][] output = new int[t1Shape.row][t1Shape.column];
+
+ for(int i = 0; i < t1Shape.row; i++) {
+ for(int j = 0; j < t1Shape.column; j++) {
+ output[i][j] = t1.get(i, j) - t2.get(i, j);
+ }
+ }
+
+ return new Tensor2D(output);
+ } catch (ShapeMismatchException e) {
+ ep.printShapeMismatchExceptionLog();
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/Calculator.java b/src/main/java/seedu/badmaths/matrix/Calculator.java
new file mode 100644
index 0000000000..60a3a161d8
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Calculator.java
@@ -0,0 +1,29 @@
+package seedu.badmaths.matrix;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class runs the given Matrix command.
+ */
+public class Calculator {
+ Logger logger = Logger.getLogger("matrix");
+
+ /**
+ * Run the Matrix command.
+ *
+ * @param toDo given matrix expression.
+ */
+ public void run(String toDo) {
+ logger.log(Level.INFO, "Start to open calculator.");
+
+ Ui ui = new Ui();
+ Parser p = new Parser();
+ Tensor2D result;
+
+ result = p.parse(toDo);
+ if(result != null) {
+ ui.printResult(result);
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/Execute.java b/src/main/java/seedu/badmaths/matrix/Execute.java
new file mode 100644
index 0000000000..eed918e492
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Execute.java
@@ -0,0 +1,151 @@
+package seedu.badmaths.matrix;
+
+/**
+ * This class executes the given expression with given operators and operand parsed from Parser class.
+ */
+public class Execute {
+
+ /**
+ * Execute the given command with calling corresponding executing function.
+ *
+ * @param type type of the operator.
+ * @param command given matrix expression.
+ */
+ public Tensor2D execute(Parser.CalType type, String command){
+ Tensor2D result = null;
+
+ switch(type) {
+ case ADDITION:
+ result = executeAdd(command);
+ break;
+ case SUBTRACTION:
+ result = executeSub(command);
+ break;
+ case MULTIPLICATION:
+ result = executeMul(command);
+ break;
+ case ELEMENT_WISE_DOT_PRODUCT:
+ result = executeDot(command);
+ break;
+ default:
+ break;
+ }
+
+ return result;
+ }
+
+ /**
+ * Execute the matrix multiplication with calling corresponding function from Calculate class.
+ *
+ * @param command given matrix expression.
+ */
+ public Tensor2D executeMul(String command) {
+ Calculate c = new Calculate();
+
+ String[] operator = command.split("\\.\\*");
+
+ Tensor2D result;
+ Tensor2D t1 = executeTranspose(operator[0]);
+ Tensor2D t2 = executeTranspose(operator[1]);
+
+ if(t1 == null || t2 == null){
+ return null;
+ }
+
+ result = c.mul(t1, t2);
+ assert result != null;
+
+ return result;
+ }
+
+ /**
+ * Execute the matrix element wise product with calling corresponding function from Calculate class.
+ *
+ * @param command given matrix expression.
+ */
+ public Tensor2D executeDot(String command) {
+ Calculate c = new Calculate();
+
+ String[] operator = command.split("\\*");
+
+ Tensor2D result;
+ Tensor2D t1 = executeTranspose(operator[0]);
+ Tensor2D t2 = executeTranspose(operator[1]);
+
+ if(t1 == null || t2 == null){
+ return null;
+ }
+
+ result = c.dot(t1, t2);
+ assert result != null;
+
+ return result;
+ }
+
+ /**
+ * Execute the matrix addition with calling corresponding function from Calculate class.
+ *
+ * @param command given matrix expression.
+ */
+ public Tensor2D executeAdd(String command) {
+ Calculate c = new Calculate();
+
+ String[] operator = command.split("\\+");
+
+ Tensor2D result;
+ Tensor2D t1 = executeTranspose(operator[0]);
+ Tensor2D t2 = executeTranspose(operator[1]);
+
+ if(t1 == null || t2 == null){
+ return null;
+ }
+
+ result = c.add(t1, t2);
+ assert result != null;
+
+ return result;
+ }
+
+ /**
+ * Execute the matrix subtraction with calling corresponding function from Calculate class.
+ *
+ * @param command given matrix expression.
+ */
+ public Tensor2D executeSub(String command) {
+ Calculate c = new Calculate();
+
+ String[] operator = command.split("-");
+
+ Tensor2D result;
+ Tensor2D t1 = executeTranspose(operator[0]);
+ Tensor2D t2 = executeTranspose(operator[1]);
+
+ if(t1 == null || t2 == null){
+ return null;
+ }
+
+ result = c.sub(t1, t2);
+ assert result != null;
+
+ return result;
+ }
+
+ /**
+ * Execute the matrix transposition with calling corresponding function from Calculate class.
+ *
+ * @param command given matrix expression.
+ */
+ public Tensor2D executeTranspose(String command) {
+ String operator;
+ Tensor2D output;
+
+ if(command.contains(".T")) {
+ operator = command.replace(".T", "");
+ output = Parser.parseMatrix(operator);
+
+ return output != null ? output.t() : output;
+ } else {
+ return Parser.parseMatrix(command);
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/Parser.java b/src/main/java/seedu/badmaths/matrix/Parser.java
new file mode 100644
index 0000000000..e2b545a180
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Parser.java
@@ -0,0 +1,114 @@
+package seedu.badmaths.matrix;
+
+
+import seedu.badmaths.matrix.exception.ExceptionChecker;
+import seedu.badmaths.matrix.exception.ExceptionPrinter;
+import seedu.badmaths.matrix.exception.UnknownOperatorException;
+import seedu.badmaths.matrix.exception.MatrixShapeException;
+import seedu.badmaths.matrix.exception.MatrixFormatException;
+
+/**
+ * This class parses the given expression with extracting operands and operator.
+ * It also calls the corresponding function from Execute class.
+ */
+public class Parser {
+ static ExceptionChecker check = new ExceptionChecker();
+ static ExceptionPrinter ep = new ExceptionPrinter();
+
+ /**
+ * Parse the given command and execute it with returning the output.
+ *
+ * @param command given matrix expression.
+ */
+ public Tensor2D parse(String command) {
+ CalType type;
+ Tensor2D result;
+ Execute ex = new Execute();
+
+ command = command.replace(" ", "");
+
+ try {
+ check.checkUnknownOperator(command);
+
+ type = parseOp(command);
+ result = ex.execute(type, command);
+
+ return result;
+ } catch (UnknownOperatorException e) {
+ ep.printUnknownOperatorExceptionLog();
+ return null;
+ }
+ }
+
+ /**
+ * Parse the given command with discovering the type of operator.
+ * Return the corresponding CalType.
+ *
+ * @param command given matrix expression.
+ */
+ protected CalType parseOp(String command){
+ if(command.contains("]+[")) {
+ return CalType.ADDITION;
+ } else if(command.contains("]-[")) {
+ return CalType.SUBTRACTION;
+ } else if(command.contains("].*[")) {
+ return CalType.MULTIPLICATION;
+ } else if(command.contains("]*[")) {
+ return CalType.ELEMENT_WISE_DOT_PRODUCT;
+ } else {
+ return CalType.UNKNOWN;
+ }
+ }
+
+ /**
+ * Parse the matrix to Tensor2D class.
+ *
+ * @param command given matrix expression.
+ */
+ public static Tensor2D parseMatrix(String command) {
+ int[][] tensor;
+ int rowNum;
+ int colNum;
+
+ try {
+ check.checkMatrixFormat(command);
+
+ command = command.replace("[", "");
+ command = command.replace("]", "");
+
+ String[] rows;
+ String[] column;
+
+ rows = command.split(";");
+ rowNum = rows.length;
+ colNum = rows[0].split(",").length;
+
+ assert rowNum == 1 || colNum == rows[1].split(",").length;
+
+ tensor = new int[rowNum][colNum];
+ for (int i = 0; i < rowNum; i++) {
+ column = rows[i].split(",");
+ for (int j = 0; j < colNum; j++) {
+ try {
+ tensor[i][j] = Integer.parseInt(column[j]);
+ } catch (NumberFormatException e) {
+ ep.printMatrixNumericExceptionLog();
+ return null;
+ }
+ }
+ }
+ } catch (MatrixFormatException fe) {
+ ep.printMatrixFormatExceptionLog();
+ return null;
+ } catch (MatrixShapeException se) {
+ ep.printMatrixShapeExceptionLog();
+ return null;
+ }
+
+ return new Tensor2D(tensor);
+ }
+
+ enum CalType {
+ ADDITION, SUBTRACTION, MULTIPLICATION, ELEMENT_WISE_DOT_PRODUCT, UNKNOWN
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/Shape.java b/src/main/java/seedu/badmaths/matrix/Shape.java
new file mode 100644
index 0000000000..b1457eda17
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Shape.java
@@ -0,0 +1,42 @@
+package seedu.badmaths.matrix;
+
+/**
+ * Representation of the shape of the matrix.
+ */
+public class Shape {
+ protected int row;
+ protected int column;
+
+ /**
+ * Create new shape class with the specified configuration.
+ *
+ * @param row the number of the row of 2D matrix.
+ * @param column the number of the column of 2D matrix.
+ */
+ public Shape(int row, int column) {
+ this.row = row;
+ this.column = column;
+ }
+
+ /**
+ * Return the row.
+ */
+ public int getRow(){
+ return row;
+ }
+
+ /**
+ * Return the column.
+ */
+ public int getColumn(){
+ return column;
+ }
+
+ /**
+ * Print the configuration of the Shape class.
+ */
+ @Override
+ public String toString() {
+ return row + " x " + column;
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/Tensor.java b/src/main/java/seedu/badmaths/matrix/Tensor.java
new file mode 100644
index 0000000000..3853be6d21
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Tensor.java
@@ -0,0 +1,7 @@
+package seedu.badmaths.matrix;
+
+public abstract class Tensor {
+ public abstract Shape shape();
+ public abstract String toString();
+}
+
diff --git a/src/main/java/seedu/badmaths/matrix/Tensor2D.java b/src/main/java/seedu/badmaths/matrix/Tensor2D.java
new file mode 100644
index 0000000000..e5468f06c1
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Tensor2D.java
@@ -0,0 +1,95 @@
+package seedu.badmaths.matrix;
+
+/**
+ * Representation of the 2D matrix class.
+ */
+public class Tensor2D extends Tensor {
+ protected int[][] tensor;
+ protected Shape shape;
+
+ /**
+ * Create new Tensor2D class with the specified configuration.
+ *
+ * @param tensor 2D array of integer which is the value of the matrix.
+ */
+ public Tensor2D(int[][] tensor){
+ this.tensor = tensor;
+ shape = new Shape(tensor.length, tensor[0].length);
+ }
+
+ /**
+ * Return the shape of the matrix.
+ */
+ public Shape shape(){
+ return shape;
+ }
+
+ /**
+ * Return the number of row of matrix.
+ */
+ public int row(){
+ return shape.getRow();
+ }
+
+ /**
+ * Return the number of column of matrix.
+ */
+ public int column(){
+ return shape.getColumn();
+ }
+
+ /**
+ * Return the value of the matrix.
+ */
+ public int[][] tensor(){
+ return this.tensor;
+ }
+
+ /**
+ * Return the value of the given index within the matrix.
+ */
+ public int get(int row, int column){
+ return tensor[row][column];
+ }
+
+ /**
+ * Return the transposed matrix.
+ */
+ public Tensor2D t(){
+ int row = shape.row;
+ int column = shape.column;
+
+ int[][] transposeTensor = new int[column][row];
+
+ for(int i = 0; i < column; i++) {
+ for(int j = 0; j < row; j++) {
+ transposeTensor[i][j] = tensor[j][i];
+ }
+ }
+
+ return new Tensor2D(transposeTensor);
+ }
+
+ /**
+ * Print the configuration of the Tensor2D.
+ */
+ @Override
+ public String toString() {
+ int row = shape.row;
+ int column = shape.column;
+
+ StringBuilder str = new StringBuilder("");
+ str.append(" 1. shape : ").append(row).append(" x ").append(column).append("\n");
+ str.append(" 2. value : \n");
+
+ for(int i = 0; i < row; i++) {
+ str.append(" ").append(i).append(") ");
+ for(int j = 0; j < column; j++){
+ str.append(tensor[i][j]).append(" ");
+ }
+ str.append("\n");
+ }
+
+ return str.toString();
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/Ui.java b/src/main/java/seedu/badmaths/matrix/Ui.java
new file mode 100644
index 0000000000..d80f7a37cf
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/Ui.java
@@ -0,0 +1,12 @@
+package seedu.badmaths.matrix;
+
+public class Ui {
+ public void printInfo(){
+ System.out.println("");
+ }
+
+ public void printResult(Tensor2D tensor){
+ System.out.println("Result.");
+ System.out.println(tensor);
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/exception/ExceptionChecker.java b/src/main/java/seedu/badmaths/matrix/exception/ExceptionChecker.java
new file mode 100644
index 0000000000..f4ba0ede9e
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/exception/ExceptionChecker.java
@@ -0,0 +1,93 @@
+package seedu.badmaths.matrix.exception;
+
+import seedu.badmaths.matrix.Tensor2D;
+
+/**
+ * This class checks whether exception would be occurred.
+ * This class handles four exceptions below:
+ * 1. MatrixFormatException
+ * 2. MatrixShapeException
+ * 3. ShapeMismatchException
+ * 4. UnknownOperatorException
+ */
+public class ExceptionChecker {
+
+ /**
+ * Check whether shapes of the two operands match each other for the matrix calculation.
+ *
+ * @param t1 operand1
+ * @param t2 operand2
+ * @param type type of the operator
+ */
+ public void checkShapeMismatch(Tensor2D t1, Tensor2D t2, String type) throws ShapeMismatchException {
+ switch(type) {
+ case "MUL":
+ if(t1.column() != t2.row()) {
+ throw new ShapeMismatchException();
+ }
+ break;
+ case "DOT":
+ case "ADD":
+ case "SUB":
+ boolean isColumnMatch = t1.column() != t2.column();
+ boolean isRowMatch = t1.row() != t2.row();
+
+ if(isColumnMatch || isRowMatch) {
+ throw new ShapeMismatchException();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Check whether given operator is appropriate.
+ *
+ * @param command given matrix expression.
+ */
+ public void checkUnknownOperator(String command) throws UnknownOperatorException {
+ boolean isMul = command.contains("].*[");
+ boolean isDot = command.contains("]*[");
+ boolean isAdd = command.contains("]+[");
+ boolean isSub = command.contains("]-[");
+
+ if (!isMul && !isDot && !isAdd && !isSub) {
+ throw new UnknownOperatorException();
+ }
+ }
+
+ /**
+ * Check whether matrix format of the given expression is appropriate.
+ *
+ * @param matrix given matrix expression.
+ */
+ public static void checkMatrixFormat(String matrix) throws MatrixShapeException, MatrixFormatException {
+ boolean isRightWrapper = matrix.contains("[") && matrix.contains("]");
+
+ if(!isRightWrapper) {
+ throw new MatrixFormatException();
+ }
+
+ matrix = matrix.replace("[", "");
+ matrix = matrix.replace("]", "");
+
+ String[] rows;
+ String[] column;
+ int rowNum;
+ int colNum;
+
+ rows = matrix.split(";");
+ rowNum = rows.length;
+ colNum = rows[0].split(",").length;
+
+ for(int i = 0; i < rowNum; i++) {
+ column = rows[i].split(",");
+ for(int j = 0; j < colNum; j++) {
+ if(colNum != column.length) {
+ throw new MatrixShapeException();
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/exception/ExceptionPrinter.java b/src/main/java/seedu/badmaths/matrix/exception/ExceptionPrinter.java
new file mode 100644
index 0000000000..66510ee114
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/exception/ExceptionPrinter.java
@@ -0,0 +1,71 @@
+package seedu.badmaths.matrix.exception;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class prints the corresponding exception message.
+ */
+public class ExceptionPrinter {
+ Logger logger = Logger.getLogger("exception");
+
+ /**
+ * Print the exception message of ShapeMismatchException.
+ */
+ public void printShapeMismatchExceptionLog() {
+ String ExceptionMessage = "";
+ ExceptionMessage += "\n";
+ ExceptionMessage += "There is shape mismatch between t1 and t2 : cannot execute matrix calculation.";
+ System.out.println(ExceptionMessage);
+
+ logger.log(Level.WARNING, "shape mismatch occur.");
+ }
+
+ /**
+ * Print the exception message of UnknownOperatorException.
+ */
+ public void printUnknownOperatorExceptionLog() {
+ String ExceptionMessage = "";
+ ExceptionMessage += "\n";
+ ExceptionMessage += "Operator in expression is unknown.";
+ System.out.println(ExceptionMessage);
+
+ logger.log(Level.WARNING, "Unknown operator.");
+ }
+
+ /**
+ * Print the exception message of MatrixShapeException.
+ */
+ public void printMatrixShapeExceptionLog(){
+ String ExceptionMessage = "";
+ ExceptionMessage += "\n";
+ ExceptionMessage += "Length of every rows should be the same with each other.";
+ System.out.println(ExceptionMessage);
+
+ logger.log(Level.WARNING, "shape of matrix is not correct.");
+ }
+
+ /**
+ * Print the exception message of MatrixFormatException.
+ */
+ public void printMatrixFormatExceptionLog(){
+ String ExceptionMessage = "";
+ ExceptionMessage += "\n";
+ ExceptionMessage += "Format of matrix is not correct.";
+ System.out.println(ExceptionMessage);
+
+ logger.log(Level.WARNING, "Format of matrix is not correct.");
+ }
+
+ /**
+ * Print the exception message of NumericFormatException.
+ */
+ public void printMatrixNumericExceptionLog(){
+ String ExceptionMessage = "";
+ ExceptionMessage += "\n";
+ ExceptionMessage += "Every entities of matrix should be integer.";
+ System.out.println(ExceptionMessage);
+
+ logger.log(Level.WARNING, "Format of matrix is not correct.");
+ }
+}
diff --git a/src/main/java/seedu/badmaths/matrix/exception/MatrixFormatException.java b/src/main/java/seedu/badmaths/matrix/exception/MatrixFormatException.java
new file mode 100644
index 0000000000..c5b0a233fe
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/exception/MatrixFormatException.java
@@ -0,0 +1,7 @@
+package seedu.badmaths.matrix.exception;
+
+/**
+ * Exception that occurs when the matrix format of the given expression is not correct.
+ */
+public class MatrixFormatException extends Exception{
+}
diff --git a/src/main/java/seedu/badmaths/matrix/exception/MatrixShapeException.java b/src/main/java/seedu/badmaths/matrix/exception/MatrixShapeException.java
new file mode 100644
index 0000000000..a65c47e413
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/exception/MatrixShapeException.java
@@ -0,0 +1,7 @@
+package seedu.badmaths.matrix.exception;
+
+/**
+ * Exception that occurs when the shape of the matrix is not correct.
+ */
+public class MatrixShapeException extends Exception {
+}
diff --git a/src/main/java/seedu/badmaths/matrix/exception/ShapeMismatchException.java b/src/main/java/seedu/badmaths/matrix/exception/ShapeMismatchException.java
new file mode 100644
index 0000000000..f37794df6b
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/exception/ShapeMismatchException.java
@@ -0,0 +1,7 @@
+package seedu.badmaths.matrix.exception;
+
+/**
+ * Exception that occurs when the shapes of the two operands don't match with each other.
+ */
+public class ShapeMismatchException extends Exception {
+}
diff --git a/src/main/java/seedu/badmaths/matrix/exception/UnknownOperatorException.java b/src/main/java/seedu/badmaths/matrix/exception/UnknownOperatorException.java
new file mode 100644
index 0000000000..1f1438febf
--- /dev/null
+++ b/src/main/java/seedu/badmaths/matrix/exception/UnknownOperatorException.java
@@ -0,0 +1,7 @@
+package seedu.badmaths.matrix.exception;
+
+/**
+ * Exception that occurs when the given operator is unknown.
+ */
+public class UnknownOperatorException extends Exception {
+}
diff --git a/src/main/java/seedu/badmaths/note/Note.java b/src/main/java/seedu/badmaths/note/Note.java
new file mode 100644
index 0000000000..d057514795
--- /dev/null
+++ b/src/main/java/seedu/badmaths/note/Note.java
@@ -0,0 +1,69 @@
+package seedu.badmaths.note;
+
+//@@author ZiqiuZeng
+public class Note {
+ private String text; // the note information
+ private int reviewCount; // how many times the note has been reviewed
+ private boolean isDone; // whether the note is marked as done or not
+ private NotePriority.Priority priority; // the priority of the note
+
+ // constructor
+ public Note(String text, NotePriority.Priority priority) {
+ this.text = text;
+ this.reviewCount = 0;
+ this.isDone = false;
+ this.priority = priority;
+ }
+
+ public Note() {
+ }
+
+ // getters and setters
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ }
+
+ public int getReviewCount() {
+ return reviewCount;
+ }
+
+ public void incrementReviewCount() {
+ this.reviewCount++;
+ }
+
+ public boolean getIsDone() {
+ return isDone;
+ }
+ public String getIsDoneIcon() {
+ return (isDone ? "Y" : "N"); // mark done task with X
+ }
+
+ public void markAsDone() {
+ this.isDone = true;
+ }
+
+ public void markAsNotDone() {
+ this.isDone = false;
+ }
+
+ public NotePriority.Priority getPriority() {
+ return priority;
+ }
+
+ public void setPriority(NotePriority.Priority priority) {
+ this.priority = priority;
+ }
+
+ public void setReviewCount(int reviewCount) {
+ this.reviewCount = reviewCount;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + getPriority() + "]" + "[" +getIsDoneIcon() + "]" + "[" + getReviewCount() + "]" + getText();
+ }
+}
diff --git a/src/main/java/seedu/badmaths/note/NotePriority.java b/src/main/java/seedu/badmaths/note/NotePriority.java
new file mode 100644
index 0000000000..a1883ed846
--- /dev/null
+++ b/src/main/java/seedu/badmaths/note/NotePriority.java
@@ -0,0 +1,9 @@
+package seedu.badmaths.note;
+
+public class NotePriority {
+ public enum Priority {
+ LOW,
+ MEDIUM,
+ HIGH
+ }
+}
diff --git a/src/main/java/seedu/badmaths/note/NotesList.java b/src/main/java/seedu/badmaths/note/NotesList.java
new file mode 100644
index 0000000000..5352762b51
--- /dev/null
+++ b/src/main/java/seedu/badmaths/note/NotesList.java
@@ -0,0 +1,137 @@
+package seedu.badmaths.note;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+//@@author ZiqiuZeng
+public class NotesList {
+
+ //@@author ZiqiuZeng
+ protected ArrayList notes;
+
+ //@@author ZiqiuZeng
+ public NotesList(ArrayList notes) {
+ this.notes = notes;
+ }
+
+ //@@author ZiqiuZeng
+ public void reset() {
+ notes.clear();
+ notes = new ArrayList<>();
+ }
+
+ //@@author ZiqiuZeng
+ public void add(String text) {
+ NotePriority.Priority priority = NotePriority.Priority.LOW;
+ Note note = new Note(text, priority);
+ notes.add(note);
+ }
+
+ //@@author ZiqiuZeng
+ public void remove(int index) {
+ notes.remove(index);
+ }
+
+ //@@author ZiqiuZeng
+ public void markAsDone(int index) {
+ Note note = notes.get(index);
+ note.markAsDone();
+ }
+
+ //@@author ZiqiuZeng
+ public void markAsUndone(int index) {
+ Note note = notes.get(index);
+ note.markAsNotDone();
+ }
+
+ //@@author ZiqiuZeng
+ public void setPriority(int index, NotePriority.Priority priority) {
+ Note note = notes.get(index);
+ note.setPriority(priority);
+ }
+
+ //@@author ZiqiuZeng
+ public String getText(int index) {
+ return notes.get(index).toString();
+ }
+
+ //@@author ZiqiuZeng
+ public void review(int index) {
+ Note note = notes.get(index);
+ note.incrementReviewCount();
+ }
+
+ //@@author ZiqiuZeng
+ public ArrayList getAll() {
+ return notes;
+ }
+
+ //@@author ZiqiuZeng
+ public int getSize() {
+ return notes.size();
+ }
+
+ //@@author ZiqiuZeng
+ public ArrayList relevantInfo(String keyword) {
+ ArrayList relevantNotes = new ArrayList<>();
+ for (Note note : notes) {
+ if (note.getText().contains(keyword)) {
+ relevantNotes.add(note);
+ }
+ }
+ return relevantNotes;
+ }
+
+ //@@author ZiqiuZeng
+ public ArrayList relevantPriority(String priorityStr) {
+ NotePriority.Priority priority = NotePriority.Priority.valueOf(priorityStr);
+ ArrayList relevantNotes = new ArrayList<>();
+ for (Note note : notes) {
+ if (note.getPriority() == priority) {
+ relevantNotes.add(note);
+ }
+ }
+ return relevantNotes;
+ }
+
+ //@@author ZiqiuZeng
+ public ArrayList relevantMarked() {
+ ArrayList markedNotes = new ArrayList<>();
+ for (Note note : notes) {
+ if (note.getIsDone()) {
+ markedNotes.add(note);
+ }
+ }
+ return markedNotes;
+ }
+
+ //@@author ZiqiuZeng
+ public ArrayList relevantUnmarked() {
+ ArrayList unmarkedNotes = new ArrayList<>();
+ for (Note note : notes) {
+ if (!note.getIsDone()) {
+ unmarkedNotes.add(note);
+ }
+ }
+ return unmarkedNotes;
+ }
+
+ //@@author ZiqiuZeng
+ public void rankByReviewCount() {
+ notes.sort((note1, note2) -> Integer.compare(note2.getReviewCount(), note1.getReviewCount()));
+ }
+
+ //@@author ZiqiuZeng
+ public void rankByPriority() {
+ Collections.sort(notes, new Comparator() {
+ @Override
+ public int compare(Note note1, Note note2) {
+ NotePriority.Priority priority1 = note1.getPriority();
+ NotePriority.Priority priority2 = note2.getPriority();
+ return priority2.compareTo(priority1);
+ }
+ });
+ }
+
+}
diff --git a/src/main/java/seedu/badmaths/storage/InvalidNotesFileHandler.java b/src/main/java/seedu/badmaths/storage/InvalidNotesFileHandler.java
new file mode 100644
index 0000000000..f6ee3f8c7e
--- /dev/null
+++ b/src/main/java/seedu/badmaths/storage/InvalidNotesFileHandler.java
@@ -0,0 +1,63 @@
+package seedu.badmaths.storage;
+
+import seedu.badmaths.note.Note;
+
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import static seedu.badmaths.storage.NotesFileParser.loadFile;
+
+public class InvalidNotesFileHandler {
+ /**
+ * Handles the response from user when an invalid format exception occurs while trying to load a notes file.
+ * Gives the user the option to reset the file and clears the note list,
+ * or exit the program if the user chooses not to reset the file.
+ *
+ * @param path the file path of the notes file
+ * @param notes the list of notes to clear if the user chooses to reset the file
+ */
+ public static void responseHandler(String path, ArrayList notes) {
+ try{
+ Scanner inputScanner = new Scanner(System.in);
+ System.out.println("Sorry, your notes file seems to be corrupted :(");
+ System.out.println("Do you want to reset the file? (y/n)");
+ System.out.println("");
+ String userInput = inputScanner.nextLine().trim().toLowerCase();
+ if (userInput.equals("y")) {
+ // clear the file contents if the user confirms
+ PrintWriter writer = new PrintWriter(path);
+ writer.print("");
+ writer.close();
+
+ // clear the note list if the user confirms
+ notes.clear();
+
+ System.out.println("File contents have rest successfully.");
+ System.out.println("You can continue to use the application");
+ System.out.println("If you want to read Help Manual, " +
+ "please type 'Help' to learn what I can do for you.");
+ } else if (userInput.equals("n")){
+ System.out.println("You choose not to rest the file.");
+ System.out.println("Please ensure your file status before using the application.");
+ System.out.println("The program will exit in 10 seconds. See you next time.");
+ Timer timer = new Timer();
+ TimerTask exitTask = new TimerTask() {
+ @Override
+ public void run() {
+ System.exit(0);
+ }
+ };
+ timer.schedule(exitTask, 10000);
+ } else {
+ System.out.println("Invalid input. Please enter 'y' or 'n'.");
+ loadFile(path);
+ }
+ } catch (FileNotFoundException eForInvalidFormatException) {
+ System.out.println(eForInvalidFormatException.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/seedu/badmaths/storage/NoteParser.java b/src/main/java/seedu/badmaths/storage/NoteParser.java
new file mode 100644
index 0000000000..a781d51304
--- /dev/null
+++ b/src/main/java/seedu/badmaths/storage/NoteParser.java
@@ -0,0 +1,74 @@
+package seedu.badmaths.storage;
+
+import seedu.badmaths.InvalidFormatException;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotePriority;
+
+import java.util.Set;
+
+public class NoteParser {
+ /**
+ * Parses a string representation of a note into a Note object.
+ *
+ * @param noteString the string representation of the note in the format "Priority \t Status \t Count \t Note"
+ * @return a Note object corresponding to the parsed string representation
+ * @throws InvalidFormatException if the input string is not in the expected format or contains invalid values
+ */
+ public static Note parseNoteString(String noteString) throws InvalidFormatException{
+
+ //text format: Priority \\t Status \\t Count \\t Note
+ String[] noteInfo = noteString.split("\\t");
+
+ if (noteInfo.length != 4) {
+ throw new InvalidFormatException();
+ }
+
+ //priority
+ String priorityStr = noteInfo[0];
+ Set validPriorities = Set.of("LOW", "MEDIUM", "HIGH");
+ if (!validPriorities.contains(priorityStr)) {
+ //priorityStr is invalid, handle the error
+ throw new InvalidFormatException();
+ }
+ NotePriority.Priority priority = NotePriority.Priority.valueOf(priorityStr);
+
+ //note
+ String noteStr = noteInfo[3];
+
+ //count
+ String reviewCountStr = noteInfo[2];
+ int reviewCount;
+ //reviewCountStr is invalid, handle the error
+ try {
+ reviewCount = Integer.parseInt(reviewCountStr);
+ } catch (NumberFormatException e) {
+ throw new InvalidFormatException();
+ }
+
+ //status
+ String isDoneStr = noteInfo[1];
+ Set validIsDoneStatus = Set.of("Y", "N");
+ if(!validIsDoneStatus.contains(isDoneStr)){
+ //isDoneStr is invalid, handle the error
+ throw new InvalidFormatException();
+ }
+ boolean isDone = isDoneStr.equals("Y");
+
+ /*
+ * update notes if the file is valid
+ */
+ //update text, priority
+ Note note = new Note(noteStr, priority);
+ //update status
+ if(isDone) {
+ note.markAsDone();
+ } else {
+ note.markAsNotDone();
+ }
+ //update count
+ note.setReviewCount(reviewCount);
+
+ //add note
+ return note;
+ }
+}
diff --git a/src/main/java/seedu/badmaths/storage/NotesFileCleaner.java b/src/main/java/seedu/badmaths/storage/NotesFileCleaner.java
new file mode 100644
index 0000000000..a4016c47dc
--- /dev/null
+++ b/src/main/java/seedu/badmaths/storage/NotesFileCleaner.java
@@ -0,0 +1,25 @@
+package seedu.badmaths.storage;
+
+import java.io.FileWriter;
+import java.io.IOException;
+
+public class NotesFileCleaner {
+ /**
+ * Clears the contents of the file at the specified path.
+ *
+ * @param path the path of the file to be cleared
+ */
+ public static void clearFile(String path) {
+ try {
+ FileWriter fileWriter = new FileWriter(path);
+ fileWriter.write("");
+ fileWriter.close();
+ System.out.println("File content cleared successfully!");
+ } catch (IOException e) {
+ System.out.println("An error occurred while clearing the file content.");
+ e.printStackTrace();
+ }
+ }
+}
+
+
diff --git a/src/main/java/seedu/badmaths/storage/NotesFileContentManager.java b/src/main/java/seedu/badmaths/storage/NotesFileContentManager.java
new file mode 100644
index 0000000000..b1f5283e2c
--- /dev/null
+++ b/src/main/java/seedu/badmaths/storage/NotesFileContentManager.java
@@ -0,0 +1,43 @@
+package seedu.badmaths.storage;
+
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotePriority;
+
+import java.util.ArrayList;
+
+public class NotesFileContentManager {
+ /**
+ * Returns a string representing the contents of a list of notes.
+ *
+ * @param notes the list of notes to be represented by a string
+ * @return a string representing the contents of the list of notes
+ */
+ public static String fileContent(ArrayList notes) {
+ StringBuilder content = new StringBuilder();
+ for(Note note : notes) {
+ //priority
+ NotePriority.Priority priority = note.getPriority();
+ String priorityStr = priority.name();
+ content.append(priorityStr).append("\t");
+ //status
+ boolean isDone = note.getIsDone();
+ String isDoneStatus = "N";
+ if(isDone) {
+ isDoneStatus = "Y";
+ }
+ content.append(isDoneStatus).append("\t");
+ //count
+ int reviewCount = note.getReviewCount();
+ String reviewCountStr = String.valueOf(reviewCount);
+ content.append(reviewCountStr).append("\t");
+ //text
+ String noteText = note.getText();
+ content.append(noteText);
+ //line separator
+ content.append(System.getProperty("line.separator"));
+ }
+ return content.toString();
+ }
+}
+
+
diff --git a/src/main/java/seedu/badmaths/storage/NotesFileParser.java b/src/main/java/seedu/badmaths/storage/NotesFileParser.java
new file mode 100644
index 0000000000..18ba7da57a
--- /dev/null
+++ b/src/main/java/seedu/badmaths/storage/NotesFileParser.java
@@ -0,0 +1,38 @@
+package seedu.badmaths.storage;
+
+import seedu.badmaths.InvalidFormatException;
+import seedu.badmaths.note.Note;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Scanner;
+
+import static seedu.badmaths.storage.NoteParser.parseNoteString;
+
+public class NotesFileParser {
+ /**
+ * Loads the contents of a notes file at the specified path
+ * and returns a list of Note objects representing the file's contents.
+ *
+ * @param path the path of the notes file to be loaded
+ * @return a list of Note objects representing the contents of the specified file
+ */
+ public static ArrayList loadFile(String path) {
+ ArrayList notes = new ArrayList<>();
+ try {
+ Scanner scanner = new Scanner(new File(path));
+ String noteScanner;
+ while (scanner.hasNextLine()) {
+ noteScanner = scanner.nextLine();
+ notes.add(parseNoteString(noteScanner));
+ }
+ } catch (FileNotFoundException e) {
+ System.out.println(e.getMessage());
+ } catch (InvalidFormatException e) {
+ InvalidNotesFileHandler.responseHandler(path, notes);
+ }
+ return notes;
+ }
+}
+
diff --git a/src/main/java/seedu/badmaths/storage/NotesFileWriter.java b/src/main/java/seedu/badmaths/storage/NotesFileWriter.java
new file mode 100644
index 0000000000..3293c11c05
--- /dev/null
+++ b/src/main/java/seedu/badmaths/storage/NotesFileWriter.java
@@ -0,0 +1,42 @@
+package seedu.badmaths.storage;
+
+import seedu.badmaths.note.Note;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import static seedu.badmaths.storage.NotesFileContentManager.fileContent;
+
+public class NotesFileWriter {
+ /**
+ * Saves the list of notes to a file.
+ *
+ * @param path the path to the file to save
+ * @param notes the list of notes to save
+ */
+ public static void saveFile(String path, ArrayList notes) {
+ File file = new File(path);
+ if (!file.exists()) {
+ System.out.println("File not exists, create it ...");
+ if (!file.getParentFile().exists()) {
+ System.out.println("Directory not exists, create it ...");
+ file.getParentFile().mkdirs();
+ }
+ try {
+ file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ FileWriter fl = new FileWriter(path);
+ fl.write(fileContent(notes));
+ fl.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
+
diff --git a/src/main/java/seedu/badmaths/trigograph/GraphException.java b/src/main/java/seedu/badmaths/trigograph/GraphException.java
new file mode 100644
index 0000000000..0d15653afd
--- /dev/null
+++ b/src/main/java/seedu/badmaths/trigograph/GraphException.java
@@ -0,0 +1,5 @@
+package seedu.badmaths.trigograph;
+
+public class GraphException extends Exception{
+
+}
diff --git a/src/main/java/seedu/badmaths/trigograph/NegativeFrequencyException.java b/src/main/java/seedu/badmaths/trigograph/NegativeFrequencyException.java
new file mode 100644
index 0000000000..592472b735
--- /dev/null
+++ b/src/main/java/seedu/badmaths/trigograph/NegativeFrequencyException.java
@@ -0,0 +1,4 @@
+package seedu.badmaths.trigograph;
+
+public class NegativeFrequencyException extends Exception{
+}
diff --git a/src/main/java/seedu/badmaths/trigograph/TrigoGraph.java b/src/main/java/seedu/badmaths/trigograph/TrigoGraph.java
new file mode 100644
index 0000000000..f564e77253
--- /dev/null
+++ b/src/main/java/seedu/badmaths/trigograph/TrigoGraph.java
@@ -0,0 +1,85 @@
+package seedu.badmaths.trigograph;
+
+import seedu.badmaths.IllegalTodoException;
+import seedu.badmaths.ui.Ui;
+
+import java.awt.HeadlessException;
+
+
+public class TrigoGraph {
+ private String trigoEqn;
+ private double amplitude;
+ private double frequency;
+ private double phase;
+ private double verticalShift;
+ private String trig;
+
+ public TrigoGraph(String trigoEqn) {
+ this.trigoEqn = trigoEqn;
+ }
+
+ public void startGraphAnalysis() throws IllegalTodoException {
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(trigoEqn);
+ if (trigoEqn.isEmpty()) {
+ throw new IllegalTodoException();
+ }
+ try {
+ if (analyser.canStartAnalyser()) {
+ getGraphDetails(analyser);
+ printGraphDetails();
+ TrigoGraphVisualiser visualiser = new TrigoGraphVisualiser(amplitude, phase, frequency, verticalShift,
+ trig);
+ visualiser.startVisualiser();
+ } else {
+ throw new IllegalTodoException();
+ }
+ } catch (IllegalTodoException e) {
+ throw new IllegalTodoException();
+ } catch (HeadlessException e) {
+ assert true;
+ }
+
+ }
+
+ public void getGraphDetails(TrigoGraphAnalyser analyser) {
+ amplitude = analyser.getAmplitude();
+ frequency = analyser.getFreq();
+ phase = analyser.getPhase();
+ verticalShift = analyser.getVerticalShift();
+ trig = analyser.getTrigonometry();
+ assert true : "Information retrieved.";
+ }
+
+
+ public void printGraphDetails() {
+ if (trig.equals("tan")) {
+ Ui.printTanHasNoAmplitude();
+ } else {
+ Ui.printAmplitude(amplitude);
+ }
+ Ui.printFrequency(frequency);
+ Ui.printPhase(phase);
+ Ui.printVerticalShift(verticalShift);
+ assert true : "Information printed.";
+ }
+
+ public double getAmplitude() {
+ return amplitude;
+ }
+
+ public double getFrequency() {
+ return frequency;
+ }
+
+ public double getPhase() {
+ return phase;
+ }
+
+ public double getVerticalShift() {
+ return verticalShift;
+ }
+
+ public String getTrig() {
+ return trig;
+ }
+}
diff --git a/src/main/java/seedu/badmaths/trigograph/TrigoGraphAnalyser.java b/src/main/java/seedu/badmaths/trigograph/TrigoGraphAnalyser.java
new file mode 100644
index 0000000000..7d665834e9
--- /dev/null
+++ b/src/main/java/seedu/badmaths/trigograph/TrigoGraphAnalyser.java
@@ -0,0 +1,335 @@
+package seedu.badmaths.trigograph;
+
+
+import seedu.badmaths.ui.Ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.FileHandler;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+public class TrigoGraphAnalyser {
+ private static final boolean CAN_RUN_ANALYSER = true;
+ private static final boolean CANNOT_RUN_ANALYSER = false;
+ private static final int PLACEHOLDER_SIZE_WITH_NEG_PHASE = 3;
+ private static final int PLACEHOLDER_SIZE_WITH_POS_PHASE = 2;
+ private static final int PLACEHOLDER_SIZE_WITH_TRIGO_AND_VERTICAL_SHIFT = 2;
+ private static final int PLACEHOLDER_SIZE_WITH_AMPLITUDE_AND_EQN = 2;
+ private static final int INDEX_FOR_NEG_PHASE_WITH_NEG_FREQ = 2;
+ private static final int INDEX_FOR_NEG_PHASE_WITH_POS_FREQ = 1;
+ private static final int INDEX_FOR_FREQ_WITH_POS_PHASE = 0;
+ private static final int INDEX_FOR_POS_FREQ = 0;
+ private static final int INDEX_FOR_POS_PHASE = 1;
+ private static final int INDEX_FOR_NEG_FREQ = 1;
+ private static final int START_POS_OF_TRIG = 0;
+ private static final int END_POS_OF_TRIG = 3;
+ private static final int CORRECT_POS_OF_PHASE = 4;
+ private static final double ONE_HERTZ = 1.0;
+ private static final double ONE_AMPLITUDE = 1.0;
+ private static final double ZERO_PHASE = 0.0;
+ private static final double ZERO_VERTICAL_SHIFT = 0.0;
+ private static final double NEGATIVE_SIGN = -1.0;
+ private static final double ZERO_HERTZ = 0.0;
+ private static final int FIRST_INDEX_FOR_FREQ = 0;
+ private static final String STRING_NEGATIVE_SIGN = "-";
+ private static final String STRING_POSITIVE_SIGN = "+";
+ private static Logger logger = Logger.getLogger(TrigoGraphAnalyser.class.getName());
+ private String trigoEqn;
+ private String trigonometry;
+ private double phase;
+ private double amplitude;
+ private double verticalShift;
+ private double freq;
+
+
+ public TrigoGraphAnalyser(String trigoEqn) {
+ this.trigoEqn = trigoEqn;
+ }
+
+ public static void setUpLogger() {
+ LogManager.getLogManager().reset();
+ logger.setLevel(Level.ALL);
+ try {
+ if (!new File("trigoGraphAnalyser.log").exists()) {
+ new File("trigoGraphAnalyser.log").createNewFile();
+ }
+ FileHandler logFile = new FileHandler("trigoGraphAnalyser.log", true);
+ logFile.setLevel(Level.FINE);
+ logger.addHandler(logFile);
+
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "File logger not working.", e);
+ }
+ }
+
+ public String getTrig() {
+ return trigonometry;
+ }
+
+ /**
+ * Main method that calls various methods to split the equation into Amplitude, Frequency, Phase Shift,
+ * and Vertical Shift. This method also catches the exceptions thrown and prints out the corresponding message to
+ * the user.
+ *
+ * @return true if equation entered is valid.
+ */
+ public boolean canStartAnalyser() {
+ setUpLogger();
+ try {
+ String[] amplitudeAndEqn = splitAmplitudeFromTrigoEqn();
+ findAmplitude(amplitudeAndEqn);
+ String[] trigoAndVerticalShift;
+ // To handle the situation if equation starts with tan or 1*tan
+ if (isAmplitudeEqualsToOne(amplitudeAndEqn[0])) {
+ trigoAndVerticalShift = splitTrigoAndVerticalShift(trigoEqn);
+ } else {
+ trigoAndVerticalShift = splitTrigoAndVerticalShift(amplitudeAndEqn[1]);
+ }
+ findVerticalShift(trigoAndVerticalShift);
+ String trigo = trigoAndVerticalShift[0];
+ splitTrigoIntoPhasors(trigo);
+ return CAN_RUN_ANALYSER;
+ } catch (NumberFormatException e) {
+ logger.log(Level.SEVERE, "NumberFormatException", e);
+ return CANNOT_RUN_ANALYSER;
+ } catch (GraphException e) {
+ logger.log(Level.SEVERE, "GraphException", e);
+ Ui.printNegativeAmplitudeEntered();
+ return CANNOT_RUN_ANALYSER;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ logger.log(Level.SEVERE, "ArrayIndexOutOfBounds", e);
+ return CANNOT_RUN_ANALYSER;
+ } catch (IllegalArgumentException e) {
+ logger.log(Level.SEVERE, "IllegalArguementException", e);
+ return CANNOT_RUN_ANALYSER;
+ } catch (NegativeFrequencyException e) {
+ Ui.printNegativeFrequencyEntered();
+ return CANNOT_RUN_ANALYSER;
+ } catch (ZeroFrequencyException e) {
+ Ui.printZeroFrequencyEntered();
+ return CANNOT_RUN_ANALYSER;
+ }
+ }
+
+ /**
+ * Assigns an int to this amplitude.
+ *
+ * @param eqn contains the value of amplitude at index 0 and the remaining equation at index 1.
+ * @throws NumberFormatException if Double.parseDouble attempts to parse a non-numerical string such as "abc".
+ */
+ public void findAmplitude(String[] eqn) throws NumberFormatException {
+ String[] trigoAndVerticalShift;
+
+ if (isAmplitudeEqualsToOne(eqn[0])) {
+ amplitude = ONE_AMPLITUDE;
+ } else {
+ amplitude = Double.parseDouble(eqn[0]);
+ }
+ }
+
+ private void testForSignOfAmplitude() throws GraphException {
+ if (trigoEqn.startsWith("-")) {
+ throw new GraphException();
+ }
+ }
+
+ public void testForMultipleAsterisk(String input) throws NumberFormatException {
+ if (input.startsWith("*")) {
+ throw new NumberFormatException();
+ }
+ }
+
+ public String[] splitAmplitudeFromTrigoEqn() throws GraphException,
+ NumberFormatException, ArrayIndexOutOfBoundsException {
+ testForSignOfAmplitude();
+ String[] amplitudeAndEqn = trigoEqn.split("\\*", PLACEHOLDER_SIZE_WITH_AMPLITUDE_AND_EQN);
+ testForMultipleAsterisk(amplitudeAndEqn[1]);
+ return amplitudeAndEqn;
+ }
+
+ public Double getAmplitude() {
+ return amplitude;
+ }
+
+ public double getPhase() {
+ return phase;
+ }
+
+ public double getVerticalShift() {
+ return verticalShift;
+ }
+
+ public double getFreq() {
+ return freq;
+ }
+
+ public String getTrigonometry() {
+ return trigonometry;
+ }
+
+ private boolean isAmplitudeEqualsToOne(String input) {
+ if (input.startsWith("cos") || input.startsWith("sin") || input.startsWith("tan")) {
+ return true;
+ }
+ return false;
+ }
+
+
+ private boolean isVerticalShiftZero(String verticalShift) {
+ return verticalShift.isEmpty();
+ }
+
+
+ private String[] splitTrigoAndVerticalShift(String eqn) {
+
+ String[] trigoAndVerticalShift = eqn.split("\\)", PLACEHOLDER_SIZE_WITH_TRIGO_AND_VERTICAL_SHIFT);
+ return trigoAndVerticalShift;
+ }
+
+ private void findVerticalShift(String[] trigoAndVerticalShift) {
+ if (isVerticalShiftZero(trigoAndVerticalShift[1])) {
+ verticalShift = ZERO_VERTICAL_SHIFT;
+ } else {
+ verticalShift = Double.parseDouble(trigoAndVerticalShift[1]);
+ }
+ }
+
+ /**
+ * Remove the closing bracket in {@code trigo} to form a proper trigonometric equation containing frequency and
+ * phase.
+ *
+ * @param trigo is a trigo equation with amplitude and vertical shift removed
+ * @throws IllegalArgumentException
+ * @throws NegativeFrequencyException
+ * @throws ZeroFrequencyException
+ */
+ public void splitTrigoIntoPhasors(String trigo) throws IllegalArgumentException, NegativeFrequencyException,
+ ZeroFrequencyException {
+ int startPosOfPhase = trigo.indexOf("(") + 1;
+ int endPosOfPhase = trigo.length();
+ if (startPosOfPhase == CORRECT_POS_OF_PHASE) {
+ trigonometry = trigo.substring(START_POS_OF_TRIG, END_POS_OF_TRIG);
+ } else {
+ throw new IllegalArgumentException();
+ }
+
+ String phase = trigo.substring(startPosOfPhase, endPosOfPhase);
+ splitPhasorsIntoFreq(phase);
+ }
+
+ public void findFreqForNoPhasors(String phasors) throws NegativeFrequencyException, ZeroFrequencyException {
+ phase = ZERO_PHASE;
+ boolean isFreqNegative = testForNegativeFreq(phasors);
+ findFreq(phasors, isFreqNegative);
+ }
+
+ /*
+ * In the event that the phase is positive, this method will find the phase and frequency.
+ * @param phasors contain frequency and phase
+ * @throws NegativeFrequencyException
+ * @throws ZeroFrequencyException
+ */
+ private void findFreqForPlus(String phasors) throws NegativeFrequencyException, ZeroFrequencyException {
+ String[] freqAndShift = phasors.split("\\+", PLACEHOLDER_SIZE_WITH_POS_PHASE);
+ findPhase(freqAndShift[INDEX_FOR_POS_PHASE], false);
+ boolean isFreqNegative = testForNegativeFreq(freqAndShift[INDEX_FOR_FREQ_WITH_POS_PHASE]);
+ findFreq(freqAndShift[INDEX_FOR_POS_FREQ], isFreqNegative);
+ }
+
+ private void findFreqForMinus(String phasors) throws NegativeFrequencyException, ZeroFrequencyException {
+ /*
+ * If both phase and frequency are negative, empty string will be in index 0,freq will be in index 1,
+ * and phase will be in index 2 of freqAndShift.
+ * However, if only phase is negative, freq will be in index 0, phase will be in index 1, and empty string will
+ * in index 2.
+ */
+ String[] freqAndShift = phasors.split(STRING_NEGATIVE_SIGN, PLACEHOLDER_SIZE_WITH_NEG_PHASE);
+ boolean isPhaseNegative = true;
+ // Find if freq is negative based on its index in freqAndShift as mentioned above
+ boolean isFreqNegative = testForNegativeFreq(freqAndShift);
+ if (isFreqNegative) {
+ findPhase(freqAndShift[INDEX_FOR_NEG_PHASE_WITH_NEG_FREQ], isPhaseNegative);
+ findFreq(freqAndShift[INDEX_FOR_NEG_FREQ], isFreqNegative);
+ } else {
+ findPhase(freqAndShift[INDEX_FOR_NEG_PHASE_WITH_POS_FREQ], isPhaseNegative);
+ findFreq(freqAndShift[INDEX_FOR_POS_FREQ], isFreqNegative);
+ }
+ }
+
+ private void splitPhasorsIntoFreq(String phasors) throws NegativeFrequencyException, ZeroFrequencyException {
+ if (phasors.endsWith("x")) {
+ findFreqForNoPhasors(phasors);
+ } else if (phasors.contains(STRING_POSITIVE_SIGN)) {
+ findFreqForPlus(phasors);
+ } else {
+ findFreqForMinus(phasors);
+ }
+ }
+
+ private boolean testForNegativeFreq(String[] freqAndShift) {
+ if (freqAndShift[INDEX_FOR_POS_FREQ].isEmpty()) {
+ return true;
+ }
+ return false;
+ }
+
+ public boolean testForNegativeFreq(String freq) {
+ if (freq.startsWith(STRING_NEGATIVE_SIGN)) {
+ return true;
+ }
+ return false;
+ }
+
+ public void findFreq(String freqWithX, boolean isFreqNeg) throws NumberFormatException, NegativeFrequencyException,
+ ZeroFrequencyException {
+ try {
+ if (isFreqNeg) {
+ throw new NegativeFrequencyException();
+ }
+ String freqComponents;
+ if (freqWithX.equals("x")) {
+ freq = ONE_HERTZ / (2 * Math.PI);
+ } else {
+ /*
+ * freqWithX can have 1 or 2 "*", e.g. 5*pi*x or 5*x, simply split to get "5" will suffice as checks
+ * below will take "pi" into account, if any.
+ */
+ int lastIndexForFreq = freqWithX.indexOf("*");
+ freqComponents = freqWithX.substring(FIRST_INDEX_FOR_FREQ, lastIndexForFreq);
+ checkForZeroFreq(freqComponents);
+ if (trigoEqn.contains("pi")) {
+ freq = Double.parseDouble(freqComponents) / 2;
+ } else {
+ freq = Double.parseDouble(freqComponents) / (2 * Math.PI);
+ }
+ }
+ freq = Math.abs(freq);
+
+ } catch (NumberFormatException e) {
+ throw new NumberFormatException();
+ }
+ }
+
+ public void checkForZeroFreq(String freqComponents) throws ZeroFrequencyException {
+ if (Double.parseDouble(freqComponents) == ZERO_HERTZ) {
+ throw new ZeroFrequencyException();
+ }
+ }
+
+ private void findPhase(String phasor, boolean isPhaseNegative) throws NumberFormatException {
+ try {
+ if (phasor.isEmpty()) {
+ phase = ZERO_PHASE;
+ } else if (isPhaseNegative) {
+ phase = Double.parseDouble(phasor) * (NEGATIVE_SIGN);
+ } else {
+ phase = Double.parseDouble(phasor);
+ }
+ } catch (NumberFormatException e) {
+ throw new NumberFormatException();
+ }
+ }
+}
+
diff --git a/src/main/java/seedu/badmaths/trigograph/TrigoGraphVisualiser.java b/src/main/java/seedu/badmaths/trigograph/TrigoGraphVisualiser.java
new file mode 100644
index 0000000000..70a9f65195
--- /dev/null
+++ b/src/main/java/seedu/badmaths/trigograph/TrigoGraphVisualiser.java
@@ -0,0 +1,153 @@
+package seedu.badmaths.trigograph;
+
+import seedu.badmaths.IllegalTodoException;
+
+
+import java.awt.HeadlessException;
+import java.awt.Toolkit;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+
+public class TrigoGraphVisualiser extends JPanel {
+ private static final double PRECISION_OF_GRAPH = 0.00001;
+ private static final double START_TIME = 0.0;
+ private static final int ZERO_X_COORDINATES = 0;
+ private static final int ZERO_Y_COORDINATES = 0;
+ private double amplitude;
+ private double phase;
+ private double freqInHz;
+ private double verticalShift;
+ private String trig;
+ private double xMin;
+ private double xMax;
+ private double yMin;
+ private double yMax;
+
+ private boolean validState;
+
+ public TrigoGraphVisualiser(double amplitude, double phase, double freqInHz, double verticalShift, String trig)
+ throws IllegalTodoException {
+ this.amplitude = amplitude;
+ this.trig = trig;
+ this.phase = phase;
+ this.freqInHz = freqInHz;
+ this.verticalShift = verticalShift;
+ xMin = (-2 * Math.PI) / freqInHz;
+ xMax = (2 * Math.PI) / freqInHz;
+ yMin = -(amplitude + Math.abs(verticalShift)) * 2;
+ yMax = (amplitude + Math.abs(verticalShift)) * 2;
+ validState = isTrigoValid();
+ }
+
+ public boolean isTrigoValid() throws IllegalTodoException {
+ if (trig.equals("tan") || trig.equals("cos") || trig.equals("sin")) {
+ return true;
+ }
+ throw new IllegalTodoException();
+ }
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+
+
+ int width = getWidth();
+ int height = getHeight();
+
+ // Calculate scaling factors
+ double xScale = width / (xMax - xMin);
+ double yScale = height / (yMax - yMin);
+
+ // Translate to make origin at the center
+ g.translate(width / 2, height / 2);
+ createXAxis(g, xScale, yScale);
+ createYAxis(g, xScale, yScale);
+ labelOrigin(g, xScale, yScale);
+
+ if (trig.equals("sin")) {
+ drawSinCurve(g, xScale, yScale);
+ }
+ if (trig.equals("cos")) {
+ drawCosCurve(g, xScale, yScale);
+ }
+ if (trig.equals("tan")) {
+ drawTanCurve(g, xScale, yScale);
+ }
+ }
+
+ public void labelOrigin(Graphics g, double xScale, double yScale) {
+ g.drawString("0", ZERO_X_COORDINATES, ZERO_Y_COORDINATES);
+ }
+
+ public void createYAxis(Graphics g, double xScale, double yScale) {
+ g.setColor(Color.BLACK);
+ g.drawLine(ZERO_X_COORDINATES, (int) (yMin * yScale), ZERO_Y_COORDINATES, (int) (yMax * yScale));
+ g.drawString("Amplitude", ZERO_X_COORDINATES, (int) ((yMin * yScale) * 0.9));
+ }
+
+ public void createXAxis(Graphics g, double xScale, double yScale) {
+ g.setColor(Color.BLACK);
+ g.drawLine((int) (xMin * xScale), ZERO_Y_COORDINATES, (int) (xMax * xScale), ZERO_Y_COORDINATES);
+ g.drawString("time", (int) ((xMax * xScale) - 0.2 * xMax * xScale), ZERO_Y_COORDINATES);
+ }
+
+ public void drawSinCurve(Graphics g, double xScale, double yScale) {
+ g.setColor(Color.BLUE);
+ labelAmplitude(g, yScale);
+ for (double x = START_TIME; x <= xMax; x += PRECISION_OF_GRAPH) {
+ double y = amplitude * Math.sin(freqInHz * x + phase) + verticalShift;
+ int xPixel = (int) Math.round(x * xScale);
+ int yPixel = (int) Math.round(-y * yScale);
+ g.drawLine(xPixel - 1, yPixel, xPixel, yPixel);
+ }
+ }
+
+ public void labelAmplitude(Graphics g, double yScale) {
+ g.drawString(String.valueOf(verticalShift + amplitude), ZERO_X_COORDINATES,
+ (int) (Math.round(-(verticalShift + amplitude) * yScale)));
+ g.drawString(String.valueOf(verticalShift - amplitude), ZERO_X_COORDINATES,
+ (int) (Math.round(-(verticalShift - amplitude) * yScale)));
+ }
+
+ public void drawCosCurve(Graphics g, double xScale, double yScale) {
+ g.setColor(Color.RED);
+ labelAmplitude(g, yScale);
+ for (double x = START_TIME; x <= xMax; x += PRECISION_OF_GRAPH) {
+ double y = amplitude * Math.cos(freqInHz * x + phase) + verticalShift;
+ int xPixel = (int) Math.round(x * xScale);
+ int yPixel = (int) Math.round(-y * yScale);
+ g.drawLine(xPixel - 1, yPixel, xPixel, yPixel);
+ }
+ }
+
+
+ public void drawTanCurve(Graphics g, double xScale, double yScale) {
+ g.setColor(Color.BLACK);
+ for (double x = START_TIME; x <= xMax; x += PRECISION_OF_GRAPH) {
+ double y = amplitude * Math.tan(freqInHz * x + phase) + verticalShift;
+ int xPixel = (int) Math.round(x * xScale);
+ int yPixel = (int) Math.round(-y * yScale);
+ g.drawLine(xPixel - 1, yPixel, xPixel, yPixel);
+ }
+ }
+
+ public boolean isValidState() {
+ return validState;
+ }
+
+ public void startVisualiser() throws HeadlessException, IllegalTodoException {
+ JFrame frame = new JFrame("Trigonometric Graph");
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ int screenWidth = screenSize.width;
+ int screenHeight = screenSize.height;
+ frame.setSize(screenWidth / 2, screenHeight / 2);
+ frame.setLocationRelativeTo(null);
+ frame.add(new TrigoGraphVisualiser(amplitude, phase, freqInHz, verticalShift, trig));
+ frame.setVisible(true);
+ }
+
+}
diff --git a/src/main/java/seedu/badmaths/trigograph/ZeroFrequencyException.java b/src/main/java/seedu/badmaths/trigograph/ZeroFrequencyException.java
new file mode 100644
index 0000000000..2769b07487
--- /dev/null
+++ b/src/main/java/seedu/badmaths/trigograph/ZeroFrequencyException.java
@@ -0,0 +1,4 @@
+package seedu.badmaths.trigograph;
+
+public class ZeroFrequencyException extends Exception{
+}
diff --git a/src/main/java/seedu/badmaths/ui/Ui.java b/src/main/java/seedu/badmaths/ui/Ui.java
new file mode 100644
index 0000000000..ec5d335f12
--- /dev/null
+++ b/src/main/java/seedu/badmaths/ui/Ui.java
@@ -0,0 +1,199 @@
+package seedu.badmaths.ui;
+
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotePriority;
+
+import java.util.ArrayList;
+
+public class Ui {
+
+ private static String logo = "\n" +
+ "____ _ __ __ _ _\n" +
+ "| _ \\ | | | \\/ | | | | |\n" +
+ "| |_) | __ _ __| | | \\ / | __ _| |_| |__ ___\n" +
+ "| _ < / _` |/ _` | | |\\/| |/ _` | __| '_ \\/ __|\n" +
+ "| |_) | (_| | (_| | | | | | (_| | |_| | | \\__ \\\n" +
+ "|____/ \\__,_|\\__,_| |_| |_|\\__,_|\\__|_| |_|___/";
+
+
+ public static void printWelcomeMessage() {
+ System.out.println(logo + "\nYou can type 'Help' to learn what I can do for you :)");
+ }
+ public static void printLogo(){
+ System.out.println(logo);
+ }
+ public static void printTanHasNoAmplitude(){
+ System.out.println("Psss... Tangent graph has no amplitude.");
+ }
+ public static void printNegativeFrequencyEntered(){
+ System.out.println("Frequency cannot be negative.");
+ }
+ public static void printZeroFrequencyEntered(){
+ System.out.println("Frequency cannot be zero.");
+ }
+
+ public static void printIncorrectFormatEntered() {
+ System.out.println("Please enter the format as required.");
+ }
+
+ public static void printNegativeAmplitudeEntered() {
+ System.out.println("Amplitude cannot be negative!");
+ }
+
+ public static void printAmplitude(double amplitude) {
+ System.out.println("This is the amplitude: " + amplitude);
+ }
+
+ public static void printPhase(double phase) {
+ System.out.println("This is the phase: " + phase);
+ }
+
+ public static void printVerticalShift(double verticalShift) {
+ System.out.println("This is the vertical shift: " + verticalShift);
+ }
+
+ public static void printFrequency(Double freq) {
+ System.out.println("This is the freq (Hz): " + freq);
+ }
+
+ //@@author WilsonLee2000
+ public static void printInvalidNumberEntered() {
+ System.out.println("Input must be an integer!");
+ }
+
+ //@@author ZiqiuZeng
+ public static void printMark(String text) {
+ System.out.println("You have marked this note as done:");
+ System.out.println(text);
+ }
+
+ //@@author ZiqiuZeng
+ public static void printUnmark(String text) {
+ System.out.println("You have unmarked this note:");
+ System.out.println(text);
+ }
+
+ //@@author WilsonLee2000
+ public static void printAddNote(String text, int size) {
+ System.out.println("You have added this note:");
+ System.out.println(text);
+ System.out.println("Now you have " + size + " notes in the list.");
+ }
+
+ //@@author WilsonLee2000
+ public static void printDelete(String text, int size) {
+ System.out.println("You have removed this note:");
+ System.out.println(text);
+ System.out.println("Now you have " + (size - 1) + " notes in the list.");
+ }
+
+ //@@author WilsonLee2000
+ public static void printNotes(ArrayList notes) {
+ if (notes.size() == 0) {
+ System.out.println("You have no notes yet. :(");
+ } else {
+ System.out.println("Here are the notes you have stored:");
+ for (int i = 0; i < notes.size(); i++) {
+ System.out.println((i + 1) + ". " + notes.get(i).toString());
+ }
+ System.out.println("Now you have " + notes.size() + " notes in the list.");
+ }
+ }
+
+ //@@author WilsonLee2000
+ public static void printSpecificNote(int index, ArrayList notes) {
+ if (index >= 0 && index < notes.size()) {
+ Note note = notes.get(index);
+ System.out.println("Here is the note you are looking for: ");
+ System.out.println((index + 1) + ": " + note.toString());
+ } else {
+ System.out.println("Invalid note index");
+ }
+ }
+
+ //@@author ZiqiuZeng
+ public static void printFindNotes(ArrayList notes) {
+ if (notes.size() == 0) {
+ System.out.println("Sorry, no relevant results were found for this query. Please try other keywords.");
+ } else {
+ System.out.println("Here are the notes you are searching for:");
+ for (int i = 0; i < notes.size(); i++) {
+ System.out.println((i + 1) + ". " + notes.get(i).toString());
+ }
+ }
+ }
+
+ //@@author ZiqiuZeng
+ public static void printPriority(int index, ArrayList notes) {
+ NotePriority.Priority priority = notes.get(index).getPriority();
+ String priorityStr = priority.name();
+ System.out.println("You have changed its priority to " + priorityStr);
+ System.out.println((index + 1) + ": " + notes.get(index).toString());
+ }
+
+ //@@author ZiqiuZeng
+ public static void printNotesByReviewCount(ArrayList notes) {
+ // Sort notes by review count in descending order
+ notes.sort((note1, note2) -> Integer.compare(note2.getReviewCount(), note1.getReviewCount()));
+
+ // Print out notes by review count
+ System.out.println("Notes sorted by review count:");
+ for (Note note : notes) {
+ System.out.println(note.getText() + " (review count: " + note.getReviewCount() + ")");
+ }
+ }
+
+ //@@author ZiqiuZeng
+ public static void printNotesByPriority(ArrayList notes) {
+ ArrayList highPriorityNotes = new ArrayList<>();
+ ArrayList mediumPriorityNotes = new ArrayList<>();
+ ArrayList lowPriorityNotes = new ArrayList<>();
+
+ for (Note note : notes) {
+ if (note.getPriority() == NotePriority.Priority.HIGH) {
+ highPriorityNotes.add(note);
+ } else if (note.getPriority() == NotePriority.Priority.MEDIUM) {
+ mediumPriorityNotes.add(note);
+ } else {
+ lowPriorityNotes.add(note);
+ }
+ }
+
+ System.out.println("High priority notes:");
+ for (Note note : highPriorityNotes) {
+ System.out.println(note.toString());
+ }
+
+ System.out.println("Medium priority notes:");
+ for (Note note : mediumPriorityNotes) {
+ System.out.println(note.toString());
+ }
+
+ System.out.println("Low priority notes:");
+ for (Note note : lowPriorityNotes) {
+ System.out.println(note.toString());
+ }
+ }
+
+ public static void printQuadraticFormatError() {
+ System.out.println("Please use the format as shown below:");
+ System.out.println("ax^2 + bx + c");;
+ }
+
+ public static void printQuadraticAnswer(ArrayList xStore, String vertexCoordinate, boolean isMinimum) {
+ if (xStore.get(0).isNaN() || xStore.get(1).isNaN()) {
+ System.out.println("x is imaginary.");
+ } else {
+ System.out.println("x1 = " + xStore.get(0) + " , x2 = " + xStore.get(1));
+ if (isMinimum) {
+ System.out.println("There is a minimum point: " + vertexCoordinate);
+ } else {
+ System.out.println("There is a maximum point: " + vertexCoordinate);
+ }
+ }
+ }
+
+ public static void printLineBreak() {
+ System.out.println("----------------------------------------------------------------------");
+ }
+}
diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java
deleted file mode 100644
index 5c74e68d59..0000000000
--- a/src/main/java/seedu/duke/Duke.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package seedu.duke;
-
-import java.util.Scanner;
-
-public class Duke {
- /**
- * Main entry-point for the java.duke.Duke application.
- */
- public static void main(String[] args) {
- String logo = " ____ _ \n"
- + "| _ \\ _ _| | _____ \n"
- + "| | | | | | | |/ / _ \\\n"
- + "| |_| | |_| | < __/\n"
- + "|____/ \\__,_|_|\\_\\___|\n";
- System.out.println("Hello from\n" + logo);
- System.out.println("What is your name?");
-
- Scanner in = new Scanner(System.in);
- System.out.println("Hello " + in.nextLine());
- }
-}
diff --git a/src/main/resources/HelpManual.txt b/src/main/resources/HelpManual.txt
new file mode 100644
index 0000000000..c40d4d6ebf
--- /dev/null
+++ b/src/main/resources/HelpManual.txt
@@ -0,0 +1,30 @@
+------------------------------------------------------------------
+Hello! Welcome to the Help Manual for BadMaths!
+------------------------------------------------------------------
+1. Type -> Graph [equation] <- to perform graph calculations
+2. Type -> Matrix [equation] <- to perform matrix calculations
+3. Type -> Store [any_string] <- to add notes
+4. Type -> List <- to list all stored notes
+5. Type -> List [index] <- to display a particular note
+6. Type -> Delete [index] <- to delete a particular note
+7. Type -> Clear <- to delete all stored notes
+8. Type -> Mark [index] <- to mark a particular note as completed
+9. Type -> Unmark [index] <- to unmark a particular note as incomplete
+10. Type -> FindMark <- to display a list of all notes marked as completed
+11. Type -> FindUnmark <- to display a list of all notes marked as incomplete
+12. Type -> FindInfo <- to find items stored in Notes through searching for a keyword
+13. Type -> [Priority] [index] <- to change the priority of a note
+14. Type -> Rank Priority <- to display all notes of all priority rankings
+15. Type -> Rank Review Count <- to display all notes ranked by review count
+16. Type -> FindPrior [Priority] <- to display all notes of a certain priority
+17. Type -> Quadratic [equation] <- to perform quadratic calculations
+18. Type -> History <- to display a list of command history
+19. Type -> Help <- to display content of Help Manual
+20. Type -> Bye <- to exit program
+
+-------------------------------------------------------------------
+Thank you for using BadMaths. We hope that BadMaths will be a useful study tool
+in helping you to perform Mathematical Operations.
+For more details, please visit our GitHub website [https://github.com/AY2223S2-CS2113-F10-2/tp].
+If you have any queries on BadMaths, please contact [wilsonleejunwei@u.nus.edu].
+-------------------------------------------------------------------
diff --git a/src/test/java/seedu/badmaths/CommandHistoryTest.java b/src/test/java/seedu/badmaths/CommandHistoryTest.java
new file mode 100644
index 0000000000..bdd25e6334
--- /dev/null
+++ b/src/test/java/seedu/badmaths/CommandHistoryTest.java
@@ -0,0 +1,32 @@
+//@@author WilsonLee2000
+
+package seedu.badmaths;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.io.ByteArrayOutputStream;
+
+public class CommandHistoryTest {
+
+ @Test
+ void checkStoreCommand() {
+ ArrayList historyCommand = new ArrayList<>();
+ String inputCommand = "Hello";
+ CommandHistory commandHistoryTest = new CommandHistory(historyCommand);
+ commandHistoryTest.storeCommand(inputCommand);
+ assertEquals(1, historyCommand.size());
+ }
+
+ @Test
+ void checkDisplayHistory() {
+ String correctDisplayOutput = "";
+ ByteArrayOutputStream historyDisplayed = new ByteArrayOutputStream();
+ ArrayList historyCommand = new ArrayList<>();
+ CommandHistory commandHistoryTest = new CommandHistory(historyCommand);
+ commandHistoryTest.displayHistory();
+ System.setOut(new PrintStream(historyDisplayed));
+ String stringHistoryDisplayed = historyDisplayed.toString();
+ assertEquals(correctDisplayOutput, stringHistoryDisplayed);
+ }
+}
diff --git a/src/test/java/seedu/badmaths/DeleteTest.java b/src/test/java/seedu/badmaths/DeleteTest.java
new file mode 100644
index 0000000000..59a8215073
--- /dev/null
+++ b/src/test/java/seedu/badmaths/DeleteTest.java
@@ -0,0 +1,48 @@
+//@@author WilsonLee2000
+
+package seedu.badmaths;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotesList;
+import java.util.ArrayList;
+
+public class DeleteTest {
+
+ @Test
+ void checkIsInvalidIndex() {
+ int index = 1;
+ String todo = "1";
+ String itemOne = "One";
+ ArrayList notesArray = new ArrayList<>();
+ NotesList notes = new NotesList(notesArray);
+ notes.add(itemOne);
+ Delete deleteTest = new Delete(notes, todo);
+ boolean test = deleteTest.isInvalidIndex(index, notes);
+ assertEquals(true, test);
+ }
+
+ @Test
+ void checkIsAnInt() {
+ String todo = "1";
+ ArrayList notesArray = new ArrayList<>();
+ NotesList notes = new NotesList(notesArray);
+ Delete deleteTest = new Delete(notes, todo);
+ boolean test = deleteTest.isAnInt(todo);
+ assertEquals(true, test);
+ }
+
+ @Test
+ void checkDeleteNotes() {
+ String todo = "1";
+ String itemOne = "One";
+ String itemTwo = "Two";
+ ArrayList notesArray = new ArrayList<>();
+ NotesList notes = new NotesList(notesArray);
+ notes.add(itemOne);
+ notes.add(itemTwo);
+ Delete deleteTest = new Delete(notes, todo);
+ deleteTest.deleteNotes();
+ assertEquals(1, notes.getSize());
+ }
+}
diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/seedu/badmaths/DukeTest.java
similarity index 88%
rename from src/test/java/seedu/duke/DukeTest.java
rename to src/test/java/seedu/badmaths/DukeTest.java
index 2dda5fd651..c9fbfbf1b1 100644
--- a/src/test/java/seedu/duke/DukeTest.java
+++ b/src/test/java/seedu/badmaths/DukeTest.java
@@ -1,4 +1,4 @@
-package seedu.duke;
+package seedu.badmaths;
import static org.junit.jupiter.api.Assertions.assertTrue;
diff --git a/src/test/java/seedu/badmaths/IndexCheckerTest.java b/src/test/java/seedu/badmaths/IndexCheckerTest.java
new file mode 100644
index 0000000000..249a304830
--- /dev/null
+++ b/src/test/java/seedu/badmaths/IndexCheckerTest.java
@@ -0,0 +1,28 @@
+package seedu.badmaths;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.commands.IndexChecker;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotesList;
+
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class IndexCheckerTest {
+ @Test
+ public void testIsInvalidIndex() {
+
+ ArrayList notes = new ArrayList<>();
+ NotesList notesList = new NotesList(notes);
+ notesList.add("Note 1");
+ notesList.add("Note 2");
+ notesList.add("Note 3");
+
+ assertTrue(IndexChecker.isInvalidIndex(-1, notesList));
+ assertFalse(IndexChecker.isInvalidIndex(2, notesList));
+ assertFalse(IndexChecker.isInvalidIndex(0, notesList));
+ assertFalse(IndexChecker.isInvalidIndex(1, notesList));
+ }
+}
diff --git a/src/test/java/seedu/badmaths/IntegerCheckerTest.java b/src/test/java/seedu/badmaths/IntegerCheckerTest.java
new file mode 100644
index 0000000000..00b1883e04
--- /dev/null
+++ b/src/test/java/seedu/badmaths/IntegerCheckerTest.java
@@ -0,0 +1,15 @@
+package seedu.badmaths;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.commands.IntegerChecker;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+public class IntegerCheckerTest {
+ @Test
+ public void testIsAnInt() {
+ assertTrue(IntegerChecker.isAnInt("1234567890"));
+ assertFalse(IntegerChecker.isAnInt("not a number"));
+ }
+}
diff --git a/src/test/java/seedu/badmaths/ListTest.java b/src/test/java/seedu/badmaths/ListTest.java
new file mode 100644
index 0000000000..3210c7fbce
--- /dev/null
+++ b/src/test/java/seedu/badmaths/ListTest.java
@@ -0,0 +1,60 @@
+//@@author WilsonLee2000
+
+package seedu.badmaths;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.io.ByteArrayOutputStream;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotesList;
+
+public class ListTest {
+
+ @Test
+ void checkIsInvalidIndex() {
+ int index = 1;
+ String todo = "1";
+ String itemOne = "One";
+ ArrayList notesArray = new ArrayList<>();
+ NotesList notes = new NotesList(notesArray);
+ notes.add(itemOne);
+ List listTest = new List(notes, todo);
+ boolean test = listTest.isInvalidIndex(index, notes);
+ assertEquals(true, test);
+ }
+
+ @Test
+ void checkIsAnInt() {
+ String todo = "1";
+ ArrayList notesArray = new ArrayList<>();
+ NotesList notes = new NotesList(notesArray);
+ List listTest = new List(notes, todo);
+ boolean test = listTest.isAnInt(todo);
+ assertEquals(true, test);
+ }
+
+ @Test
+ void checkIsInvalidToDo() {
+ String todo = "82738232";
+ ArrayList notesArray = new ArrayList<>();
+ NotesList notes = new NotesList(notesArray);
+ List listTest = new List(notes, todo);
+ boolean test = listTest.isInvalidTodo(todo);
+ assertEquals(false, test);
+ }
+
+ @Test
+ void testListNotes() {
+ ByteArrayOutputStream listDisplayed = new ByteArrayOutputStream();
+ ArrayList notesArray = new ArrayList<>();
+ String toDo = "index";
+ NotesList notes = new NotesList(notesArray);
+ List listTest = new List(notes, toDo);
+ listTest.listNotes();
+ String correctListOutput = "";
+ System.setOut(new PrintStream(listDisplayed));
+ String stringListDisplayed = listDisplayed.toString();
+ assertEquals(correctListOutput, stringListDisplayed);
+ }
+}
diff --git a/src/test/java/seedu/badmaths/ParserTest.java b/src/test/java/seedu/badmaths/ParserTest.java
new file mode 100644
index 0000000000..069b2c0b5e
--- /dev/null
+++ b/src/test/java/seedu/badmaths/ParserTest.java
@@ -0,0 +1,39 @@
+package seedu.badmaths;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ParserTest {
+
+ @Test
+ void getCommandShouldReturnCommand() {
+ String userInput = "Store store this";
+ Parser parserTest = new Parser(userInput);
+ String commandTest = parserTest.getCommand();
+ assertEquals(commandTest, "Store");
+ }
+
+ @Test
+ void getCommandShouldIgnoreTrailingSpaces() {
+ String userInput = " Store store this ";
+ Parser parserTest = new Parser(userInput);
+ String commandTest = parserTest.getCommand();
+ assertEquals(commandTest, "Store");
+ }
+
+ @Test
+ void getToDoShouldReturnInvalidForSingleWordInput() {
+ String userInput = "Help";
+ Parser parserTest = new Parser(userInput);
+ String toDoTest = parserTest.getToDo();
+ assertEquals(toDoTest, "Invalid todo");
+ }
+ @Test
+ void getToDoShouldIgnoreMultipleSpaces() {
+ String userInput = "Quadratic lol";
+ Parser parserTest = new Parser(userInput);
+ String toDoTest = parserTest.getToDo();
+ assertEquals(toDoTest, "lol");
+ }
+}
diff --git a/src/test/java/seedu/badmaths/Quadratic/QuadraticParserTest.java b/src/test/java/seedu/badmaths/Quadratic/QuadraticParserTest.java
new file mode 100644
index 0000000000..92517d3515
--- /dev/null
+++ b/src/test/java/seedu/badmaths/Quadratic/QuadraticParserTest.java
@@ -0,0 +1,77 @@
+package seedu.badmaths.Quadratic;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class QuadraticParserTest {
+ @Test
+ void findSignOfBShouldReturnSign() {
+ String toDo = "-2.5x^2 + 5x + 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ String sign = QuadraticParser.findSignOfB();
+ assertEquals("+",sign);
+ }
+
+ @Test
+ void findStringOfBShouldReturnB() {
+ String toDo = "-2.5x^2 + 5x + 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ String B = QuadraticParser.findStringOfB();
+ assertEquals("5", B);
+ }
+
+ @Test
+ void findSignOfCShouldReturnC() {
+ String toDo = "-2.5x^2 + 5x - 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ String sign = QuadraticParser.findSignOfC();
+ assertEquals("-", sign);
+ }
+
+ @Test
+ void findAShouldReturnA() {
+ String toDo = "-2.5x^2 + 5x + 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ double A = QuadraticParser.findA();
+ assertEquals(-2.5, A);
+ }
+ @Test
+ void findStringOfCShouldReturnC() {
+ String toDo = "-2.5x^2 + 5x + 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ String C = QuadraticParser.findStringOfC();
+ assertEquals("3", C);
+ }
+
+ @Test
+ void findAIfOnlySignShouldReturnA() {
+ String toDo = "x^2 + 5.9x + 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ double A = QuadraticParser.findA();
+ assertEquals(1, A);
+ }
+ @Test
+ void findBShouldReturnB() {
+ String toDo = "-2x^2 - 5.9x + 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ double B = QuadraticParser.findB();
+ assertEquals(-5.9, B);
+ }
+
+ @Test
+ void findBIfOnlySignShouldReturnB() {
+ String toDo = "-2x^2 - x + 3";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ double B = QuadraticParser.findB();
+ assertEquals(-1, B);
+ }
+
+ @Test
+ void findCShouldReturnC() {
+ String toDo = "-2x^2 + 5x + 3.0888";
+ QuadraticParser quadraticTest = new QuadraticParser(toDo);
+ double C = QuadraticParser.findC();
+ assertEquals(3.0888, C);
+ }
+}
diff --git a/src/test/java/seedu/badmaths/Quadratic/QuadraticTest.java b/src/test/java/seedu/badmaths/Quadratic/QuadraticTest.java
new file mode 100644
index 0000000000..edfab97017
--- /dev/null
+++ b/src/test/java/seedu/badmaths/Quadratic/QuadraticTest.java
@@ -0,0 +1,32 @@
+package seedu.badmaths.Quadratic;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class QuadraticTest {
+
+ @Test
+ void quadraticFormulaShouldReturnArrayOfX() {
+ String toDo = "-2x^2 + 5x + 3";
+ Quadratic quadraticTest = new Quadratic(toDo);
+ ArrayList xStoreTest = new ArrayList<>();
+ xStoreTest = quadraticTest.quadraticFormula(-2, 5, 3);
+ assertEquals(-0.5,xStoreTest.get(0));
+ assertEquals(3.0,xStoreTest.get(1));
+ }
+
+ @Test
+ void minMaxPointFinderShouldReturnVertexCoordinate() {
+ String toDo = "-x^2 + x + 1";
+ double A = -1;
+ double B = 1;
+ double C = 1;
+ Quadratic quadraticTest = new Quadratic(toDo);
+ String coordinate = quadraticTest.minMaxPointFinder(A, B, C);
+ assertEquals("(0.5, 1.25)", coordinate);
+ }
+
+}
diff --git a/src/test/java/seedu/badmaths/StoreTest.java b/src/test/java/seedu/badmaths/StoreTest.java
new file mode 100644
index 0000000000..a35d0ae188
--- /dev/null
+++ b/src/test/java/seedu/badmaths/StoreTest.java
@@ -0,0 +1,42 @@
+//@@author WilsonLee2000
+
+package seedu.badmaths;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import java.util.ArrayList;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotesList;
+import java.nio.file.Path;
+import java.nio.file.Files;
+import java.io.IOException;
+
+public class StoreTest {
+
+ @Test
+ void checkIsInvalidToDo() throws IOException {
+ Path temporaryFile = Files.createTempFile("TempFile", ".txt");
+ String contentsFile = "HIGH\tN\t0\tThis is a first test \nMEDIUM\tY\t2\tThis is a second test\n";
+ Files.writeString(temporaryFile, contentsFile);
+ String todo = "82738232";
+ ArrayList notesArray = new ArrayList<>();
+ NotesList notes = new NotesList(notesArray);
+ Store storeTest = new Store(notes, todo);
+ boolean test = storeTest.isInvalidTodo(todo);
+ assertEquals(false, test);
+ Files.delete(temporaryFile);
+ }
+
+ @Test
+ void storeValidInputCommand() throws IOException {
+ Path temporaryFile = Files.createTempFile("TempFile", ".txt");
+ String contentsFile = "HIGH\tN\t0\tThis is a first test \nMEDIUM\tY\t2\tThis is a second test\n";
+ Files.writeString(temporaryFile, contentsFile);
+ ArrayList notesArray = new ArrayList<>();
+ String toDo = "index";
+ NotesList notes = new NotesList(notesArray);
+ Store storeTest = new Store(notes, toDo);
+ storeTest.storeNotes();
+ assertEquals(1, notes.getSize());
+ Files.delete(temporaryFile);
+ }
+}
diff --git a/src/test/java/seedu/badmaths/help/HelpManualTest.java b/src/test/java/seedu/badmaths/help/HelpManualTest.java
new file mode 100644
index 0000000000..0d1074e84b
--- /dev/null
+++ b/src/test/java/seedu/badmaths/help/HelpManualTest.java
@@ -0,0 +1,45 @@
+package seedu.badmaths.help;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.HelpManual;
+
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import java.util.logging.Logger;
+import java.util.logging.LogManager;
+import java.util.logging.Level;
+import java.util.logging.Handler;
+
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class HelpManualTest {
+ @Test
+ public void testReadHelpManual() throws IOException {
+
+ final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outContent));
+
+ Logger logger = Logger.getLogger(HelpManual.class.getName());
+ LogManager.getLogManager().reset();
+ logger.setLevel(Level.ALL);
+ Handler handler = new java.util.logging.StreamHandler(outContent, new java.util.logging.SimpleFormatter());
+ handler.setLevel(Level.ALL);
+ logger.addHandler(handler);
+
+ // Call the readHelpManual() method
+ HelpManual.readHelpManual();
+
+ // Check that the content is not null
+ assertNotNull(outContent.toString());
+
+ // Check if the output matches the expected output
+ String expectedOutput = new String(Files.readAllBytes(Paths.get("src/main/resources/HelpManual.txt")));
+ assertEquals(expectedOutput, outContent.toString());
+ }
+}
diff --git a/src/test/java/seedu/badmaths/matrix/CalculateTest.java b/src/test/java/seedu/badmaths/matrix/CalculateTest.java
new file mode 100644
index 0000000000..dffd14706a
--- /dev/null
+++ b/src/test/java/seedu/badmaths/matrix/CalculateTest.java
@@ -0,0 +1,93 @@
+package seedu.badmaths.matrix;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class CalculateTest {
+ int[][] arr = new int[][]{
+ {0, 1, 2},
+ {3, 4, 5},
+ {6, 7, 8},
+ {9, 10, 11}
+ };
+ Tensor2D tensor = new Tensor2D(arr);
+
+ int[][] arrT = new int[][]{
+ {0, 3, 6, 9},
+ {1, 4, 7, 10},
+ {2, 5, 8, 11}
+ };
+ Tensor2D tensorT = new Tensor2D(arrT);
+
+ int[][] dotResult = new int[][]{
+ {0, 1, 4},
+ {9, 16, 25},
+ {36, 49, 64},
+ {81, 100, 121}
+ };
+ Tensor2D dotResultTensor = new Tensor2D(dotResult);
+
+ int[][] mulResult = new int[][]{
+ {5, 14, 23, 32},
+ {14, 50, 86, 122},
+ {23, 86, 149, 212},
+ {32, 122, 212, 302}
+ };
+ Tensor2D mulResultTensor = new Tensor2D(mulResult);
+
+ int[][] addResult = new int[][]{
+ {0, 2, 4},
+ {6, 8, 10},
+ {12, 14, 16},
+ {18, 20, 22}
+ };
+ Tensor2D addResultTensor = new Tensor2D(addResult);
+
+ @Test
+ public void testShapeStringConversion() {
+ assertEquals("4 x 3", new Tensor2D(arr).shape().toString());
+ }
+
+ @Test
+ public void testMatrixTranspose(){
+ for(int i=0; i notes = new ArrayList<>();
+ Note note1 = new Note("This is a test note", NotePriority.Priority.HIGH);
+ Note note2 = new Note("This is another test note", NotePriority.Priority.MEDIUM);
+ note2.markAsDone();
+ note2.incrementReviewCount();
+ note2.incrementReviewCount();
+ notes.add(note1);
+ notes.add(note2);
+
+ // redirect System.in and System.out for testing
+ ByteArrayInputStream in = new ByteArrayInputStream("y\n".getBytes());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ System.setIn(in);
+ System.setOut(new PrintStream(out));
+
+ InvalidNotesFileHandler.responseHandler(tempFile.toString(), notes);
+ String expectedOutput = "Sorry, your notes file seems to be corrupted :(" + System.lineSeparator() +
+ "Do you want to reset the file? (y/n)" + System.lineSeparator() + System.lineSeparator() +
+ "File contents have rest successfully." + System.lineSeparator() +
+ "You can continue to use the application" + System.lineSeparator() +
+ "If you want to read Help Manual, please type 'Help' to learn what I can do for you."
+ + System.lineSeparator();
+ assertEquals(expectedOutput, out.toString());
+
+ // verify that the file contents were cleared
+ assertEquals("", Files.readString(tempFile));
+
+ //verify that the ArrayList contents were cleared
+ assertEquals(0, notes.size());
+
+ // clean up
+ Files.delete(tempFile);
+ System.setIn(System.in);
+ System.setOut(System.out);
+ }
+
+ @Test
+ public void testResponseHandlerExit() throws IOException {
+
+ Path tempFile = Files.createTempFile("temp", ".txt");
+ String fileContents = "HIGH\tN\t0\tThis is a test note\nMEDIUM\tY\t2\tThis is another test note\n";
+ Files.writeString(tempFile, fileContents);
+
+ // redirect System.in and System.out for testing
+ ByteArrayInputStream in = new ByteArrayInputStream("n\n".getBytes());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ System.setIn(in);
+ System.setOut(new PrintStream(out));
+
+ // create a temporary ArrayList
+ ArrayList notes = new ArrayList<>();
+ Note note1 = new Note("This is a test note", NotePriority.Priority.HIGH);
+ Note note2 = new Note("This is another test note", NotePriority.Priority.MEDIUM);
+ note2.markAsDone();
+ note2.incrementReviewCount();
+ note2.incrementReviewCount();
+ notes.add(note1);
+ notes.add(note2);
+
+ // call the responseHandler method and verify the output
+ InvalidNotesFileHandler.responseHandler(tempFile.toString(), notes);
+ String expectedOutput = "Sorry, your notes file seems to be corrupted :(" + System.lineSeparator() +
+ "Do you want to reset the file? (y/n)" + System.lineSeparator() + System.lineSeparator() +
+ "You choose not to rest the file." + System.lineSeparator() +
+ "Please ensure your file status before using the application." + System.lineSeparator() +
+ "The program will exit in 10 seconds. See you next time." + System.lineSeparator();
+ assertEquals(expectedOutput, out.toString());
+
+ // verify that the file contents were not cleared
+ assertEquals(fileContents, Files.readString(tempFile));
+
+ // clean up
+ Files.delete(tempFile);
+ System.setIn(System.in);
+ System.setOut(System.out);
+ }
+}
diff --git a/src/test/java/seedu/badmaths/storage/NoteParserTest.java b/src/test/java/seedu/badmaths/storage/NoteParserTest.java
new file mode 100644
index 0000000000..e25847b0dc
--- /dev/null
+++ b/src/test/java/seedu/badmaths/storage/NoteParserTest.java
@@ -0,0 +1,33 @@
+package seedu.badmaths.storage;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.InvalidFormatException;
+
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotePriority;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+public class NoteParserTest {
+ @Test
+ public void testParseNoteString() throws InvalidFormatException {
+ String noteString1 = "HIGH\tY\t1\tThis is a test note.";
+ Note note1 = NoteParser.parseNoteString(noteString1);
+ assertTrue(note1.getIsDone());
+ assertEquals(note1.getIsDoneIcon(), "Y");
+ assertEquals(note1.getReviewCount(), 1);
+ assertEquals(note1.getPriority(), NotePriority.Priority.HIGH);
+ assertEquals(note1.getText(), "This is a test note.");
+
+ String noteString2 = "MEDIUM\tN\t2\tThis is another test note.";
+ Note note2 = NoteParser.parseNoteString(noteString2);
+ assertFalse(note2.getIsDone());
+ assertEquals(note2.getIsDoneIcon(), "N");
+ assertEquals(note2.getReviewCount(), 2);
+ assertEquals(note2.getPriority(), NotePriority.Priority.MEDIUM);
+ assertEquals(note2.getText(), "This is another test note.");
+ }
+
+}
diff --git a/src/test/java/seedu/badmaths/storage/NotesFileCleanerTest.java b/src/test/java/seedu/badmaths/storage/NotesFileCleanerTest.java
new file mode 100644
index 0000000000..2d17563b59
--- /dev/null
+++ b/src/test/java/seedu/badmaths/storage/NotesFileCleanerTest.java
@@ -0,0 +1,39 @@
+package seedu.badmaths.storage;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+public class NotesFileCleanerTest {
+
+ @Test
+ public void testClearFile() throws IOException{
+ // set up test file and write some contents into it
+ Path tempFile = Files.createTempFile("temp", ".txt");
+ String fileContents = "This is a test file.";
+ Files.writeString(tempFile, fileContents);
+
+ // call clearFile method
+ NotesFileCleaner.clearFile(tempFile.toString());
+
+ // check that the file exists and is empty
+ File file = new File(tempFile.toString());
+ assertTrue(file.exists());
+ assertTrue(file.isFile());
+ assertFalse(file.isDirectory());
+ assertEquals(file.length(), 0);
+
+ // clean up
+ Files.delete(tempFile);
+ System.setIn(System.in);
+ System.setOut(System.out);
+ }
+
+}
diff --git a/src/test/java/seedu/badmaths/storage/NotesFileContentManagerTest.java b/src/test/java/seedu/badmaths/storage/NotesFileContentManagerTest.java
new file mode 100644
index 0000000000..04585c172e
--- /dev/null
+++ b/src/test/java/seedu/badmaths/storage/NotesFileContentManagerTest.java
@@ -0,0 +1,45 @@
+package seedu.badmaths.storage;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotePriority;
+
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class NotesFileContentManagerTest {
+
+ @Test
+ public void testFileContent() {
+
+ //create three notes
+ Note note1 = new Note("Note 1", NotePriority.Priority.HIGH);
+ note1.markAsDone();
+ note1.incrementReviewCount();
+
+ Note note2 = new Note("Note 2", NotePriority.Priority.MEDIUM);
+
+ Note note3 = new Note("Note 3", NotePriority.Priority.LOW);
+ note3.markAsDone();
+ note3.incrementReviewCount();
+ note3.incrementReviewCount();
+
+ // add notes to an ArrayList
+ ArrayList notes = new ArrayList<>();
+ notes.add(note1);
+ notes.add(note2);
+ notes.add(note3);
+
+ // call the fileContent method and check the result
+ String expectedContent = "HIGH\tY\t1\tNote 1\n" +
+ "MEDIUM\tN\t0\tNote 2\n" +
+ "LOW\tY\t2\tNote 3\n";
+ expectedContent = expectedContent.replace("\r\n", "\n").replace("\r", "\n");
+
+ String actualContent = NotesFileContentManager.fileContent(notes);
+ actualContent = actualContent.replace("\r\n", "\n").replace("\r", "\n");
+
+ assertEquals(expectedContent, actualContent);
+ }
+}
diff --git a/src/test/java/seedu/badmaths/storage/NotesFileParserTest.java b/src/test/java/seedu/badmaths/storage/NotesFileParserTest.java
new file mode 100644
index 0000000000..acea0fbc76
--- /dev/null
+++ b/src/test/java/seedu/badmaths/storage/NotesFileParserTest.java
@@ -0,0 +1,40 @@
+package seedu.badmaths.storage;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotePriority;
+
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class NotesFileParserTest {
+
+ @Test
+ public void testLoadFile() {
+
+ ArrayList expectedNotes = new ArrayList<>();
+ expectedNotes.add(new Note("Note 1", NotePriority.Priority.HIGH));
+ expectedNotes.add(new Note("Note 2", NotePriority.Priority.LOW));
+ expectedNotes.add(new Note("Note 3", NotePriority.Priority.MEDIUM));
+ expectedNotes.get(0).markAsDone();
+ expectedNotes.get(0).setReviewCount(2);
+ expectedNotes.get(1).setReviewCount(1);
+ expectedNotes.get(2).setReviewCount(0);
+ expectedNotes.get(2).markAsDone();
+
+ String filePath = "src/test/resources/TestNotes.txt";
+
+ ArrayList actualNotes = NotesFileParser.loadFile(filePath);
+ assertEquals(expectedNotes.size(), actualNotes.size());
+
+ for (int i = 0; i < expectedNotes.size(); i++) {
+ Note expectedNote = expectedNotes.get(i);
+ Note actualNote = actualNotes.get(i);
+ assertEquals(expectedNote.getText(), actualNote.getText());
+ assertEquals(expectedNote.getPriority(), actualNote.getPriority());
+ assertEquals(expectedNote.getIsDone(), actualNote.getIsDone());
+ assertEquals(expectedNote.getReviewCount(), actualNote.getReviewCount());
+ }
+ }
+}
diff --git a/src/test/java/seedu/badmaths/storage/NotesFileWriterTest.java b/src/test/java/seedu/badmaths/storage/NotesFileWriterTest.java
new file mode 100644
index 0000000000..fbefd04451
--- /dev/null
+++ b/src/test/java/seedu/badmaths/storage/NotesFileWriterTest.java
@@ -0,0 +1,65 @@
+package seedu.badmaths.storage;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.note.Note;
+import seedu.badmaths.note.NotePriority;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class NotesFileWriterTest {
+ @Test
+ public void testSaveFile() throws IOException{
+
+ Path tempFile = Files.createTempFile("temp", ".txt");
+ String fileContents = "This is a test file.";
+ Files.writeString(tempFile, fileContents);
+
+ ArrayList testNotes = new ArrayList<>();
+
+ Note note1 = new Note("Note 1", NotePriority.Priority.HIGH);
+ note1.markAsDone();
+ note1.incrementReviewCount();
+
+ Note note2 = new Note("Note 2", NotePriority.Priority.MEDIUM);
+
+ Note note3 = new Note("Note 3", NotePriority.Priority.LOW);
+ note3.markAsDone();
+ note3.incrementReviewCount();
+ note3.incrementReviewCount();
+
+ testNotes.add(note1);
+ testNotes.add(note2);
+ testNotes.add(note3);
+
+ // save the test notes to the test file
+ NotesFileWriter.saveFile(tempFile.toString(), testNotes);
+
+ // check that the file exists
+ File file = new File(tempFile.toString());
+ assertTrue(file.exists());
+
+ // check that the actual file content matches the expected string
+ String expectedContent = "HIGH\tY\t1\tNote 1\n" +
+ "MEDIUM\tN\t0\tNote 2\n" +
+ "LOW\tY\t2\tNote 3\n";
+
+ expectedContent = expectedContent.replace("\r\n", "\n").replace("\r", "\n");
+
+ String actualContent = "";
+ actualContent = new String(Files.readAllBytes(file.toPath()));
+ actualContent = actualContent.replace("\r\n", "\n").replace("\r", "\n");
+ assertEquals(expectedContent, actualContent);
+
+ // clean up
+ Files.delete(tempFile);
+ System.setIn(System.in);
+ System.setOut(System.out);
+ }
+}
diff --git a/src/test/java/seedu/badmaths/trigograph/TrigoGraphAnalyserTest.java b/src/test/java/seedu/badmaths/trigograph/TrigoGraphAnalyserTest.java
new file mode 100644
index 0000000000..4e1e507c70
--- /dev/null
+++ b/src/test/java/seedu/badmaths/trigograph/TrigoGraphAnalyserTest.java
@@ -0,0 +1,96 @@
+package seedu.badmaths.trigograph;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+
+class TrigoGraphAnalyserTest {
+ @Test
+ void noAsteriskThrowsArrayIndexOutOfBoundsException() {
+ String eqn = "sin(x)";
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(eqn);
+ assertThrows(ArrayIndexOutOfBoundsException.class, () -> {
+ analyser.splitAmplitudeFromTrigoEqn();
+ });
+ assertEquals(false, analyser.canStartAnalyser());
+ }
+
+ @Test
+ void multipleAsteriskThrowsNumberFormatException() {
+ String eqn = "2**sin(4*x+1)-6";
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(eqn);
+ assertThrows(NumberFormatException.class, () -> {
+ analyser.testForMultipleAsterisk("*sin(4*x+1)-6");
+ });
+ }
+
+ @Test
+ void zeroVerticalShiftAndOneRadians() {
+ String eqn = "2*sin(1*x-1)";
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(eqn);
+ analyser.canStartAnalyser();
+ assertEquals(0.0, analyser.getVerticalShift());
+ assertEquals(1.0 / (Math.PI * 2), analyser.getFreq());
+ }
+
+ @Test
+ void negativeAmplitudeShouldReturnIllegalArgumentException() {
+ String equation = "-2*sin(2*pi*x+1)+3";
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(equation);
+ assertEquals(false, analyser.canStartAnalyser());
+ assertThrows(GraphException.class, () -> {
+ analyser.splitAmplitudeFromTrigoEqn();
+ });
+ }
+
+ @Test
+ void amplitudeOfOneShouldReturnOne() throws GraphException {
+ String equation = "sin(2*pi*x+1)+3";
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(equation);
+ String[] input = analyser.splitAmplitudeFromTrigoEqn();
+ analyser.findAmplitude(input);
+ assertEquals(1.0, analyser.getAmplitude());
+ }
+
+ @Test
+ void wrongFreqFormat_withMinus_expectsNegativeFrequencyException() {
+ String eqn = "2*cos(-*x+5)-2";
+ TrigoGraphAnalyser test = new TrigoGraphAnalyser(eqn);
+ assertThrows(NegativeFrequencyException.class, () -> {
+ test.findFreq("-*x", test.testForNegativeFreq("-*x"));
+ });
+ }
+
+ @Test
+ void freqWithNoPhasorsExpectNoException() {
+ String freq = "5*x";
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(freq);
+ assertDoesNotThrow(() -> {
+ analyser.findFreqForNoPhasors(freq);
+ });
+ }
+
+ @Test
+ void tanHasNoAmplitude() {
+ TrigoGraphAnalyser test = new TrigoGraphAnalyser("2*tan(2*x+5)-2");
+ test.canStartAnalyser();
+ assertEquals("tan", test.getTrig());
+ }
+
+ @Test
+ void zeroFrequencyExpectZeroFrequencyException() {
+ TrigoGraphAnalyser test = new TrigoGraphAnalyser("2*tan(0*x-1)+2");
+ assertEquals(false, test.canStartAnalyser());
+ assertThrows(ZeroFrequencyException.class, () -> {
+ test.findFreq("0*x", false);
+ });
+ }
+
+ @Test
+ void negativeFrequencyReturnsTrue() {
+ TrigoGraphAnalyser test = new TrigoGraphAnalyser("2*tan(0*x-1)+2");
+
+ }
+}
diff --git a/src/test/java/seedu/badmaths/trigograph/TrigoGraphTest.java b/src/test/java/seedu/badmaths/trigograph/TrigoGraphTest.java
new file mode 100644
index 0000000000..ad1db48a5c
--- /dev/null
+++ b/src/test/java/seedu/badmaths/trigograph/TrigoGraphTest.java
@@ -0,0 +1,104 @@
+package seedu.badmaths.trigograph;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.IllegalTodoException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class TrigoGraphTest {
+ @Test
+ void invalidEqnWithMultipleBrackets() {
+ String eqn = "2*((cos(2*x+1)))";
+ TrigoGraph test = new TrigoGraph(eqn);
+ assertThrows(IllegalTodoException.class,()->{
+ test.startGraphAnalysis();
+ });
+ }
+ @Test
+ void eqnWithTrigoAsSin(){
+ String eqn = "2*sin(2*x-1)+1";
+ TrigoGraph test = new TrigoGraph(eqn);
+ try {
+ test.startGraphAnalysis();
+ assertEquals(2.0,test.getAmplitude());
+ assertEquals(2/(2*Math.PI),test.getFrequency());
+ assertEquals(-1.0,test.getPhase());
+ assertEquals(1.0,test.getVerticalShift());
+ assertEquals("sin",test.getTrig());
+ } catch (IllegalTodoException e) {
+ System.out.println("JUnit test for integrateTestForTrigoGraph failed.");
+ }
+ }
+
+ @Test
+ void emptyEqnExpectIllegalTodoException(){
+ String eqn = "";
+ TrigoGraph test = new TrigoGraph(eqn);
+ assertThrows(IllegalTodoException.class,()->{
+ test.startGraphAnalysis();
+ });
+ }
+
+ @Test
+ void integrateTestForTrigoGraph(){
+ String eqn = "1*cos(8*x+8)-1";
+ TrigoGraph test = new TrigoGraph(eqn);
+ try {
+ test.startGraphAnalysis();
+ assertEquals(1.0,test.getAmplitude());
+ assertEquals(8/(2*Math.PI),test.getFrequency());
+ assertEquals(8.0,test.getPhase());
+ assertEquals(-1.0,test.getVerticalShift());
+ assertEquals("cos",test.getTrig());
+ } catch (IllegalTodoException e) {
+ System.out.println("JUnit test for integrateTestForTrigoGraph failed.");
+ }
+ }
+
+ @Test
+ void validEqn_withMinusFreq_expectCannotStartAnalyser() {
+ String eqn = "cos(-1*x-1)-1";
+ TrigoGraphAnalyser test = new TrigoGraphAnalyser(eqn);
+ assertEquals(false, test.canStartAnalyser());
+ }
+
+ @Test
+ void validEqn_returnsCorrectDetails() {
+ String eqn = "2*tan(2*pi*x+1)-9";
+ TrigoGraph graphTest = new TrigoGraph(eqn);
+ try {
+ graphTest.startGraphAnalysis();
+ assertEquals(2.0, graphTest.getAmplitude());
+ assertEquals("tan", graphTest.getTrig());
+ assertEquals(1.0, graphTest.getFrequency());
+ assertEquals(1.0, graphTest.getPhase());
+ assertEquals(-9.0, graphTest.getVerticalShift());
+ }catch (IllegalTodoException e){
+ System.out.println("JUnit test for validEqn_returnsCorrectDetails failed.");
+ }
+ }
+
+ @Test
+ void invalidEqn_withMultipleTrigo_expectCanStartAnalyserAsFalse() {
+ String eqn1 = "2*tan*tan(2*pi*x+1)-9";
+ TrigoGraphAnalyser test = new TrigoGraphAnalyser(eqn1);
+ assertEquals(false, test.canStartAnalyser());
+
+ }
+
+ @Test
+ void invalidEqn2_withMultipleTrigo_expectCanStartAnalyserAsFalse() {
+ String eqn2 = "2*tantan(2*pi*x+1)-9";
+ TrigoGraphAnalyser test = new TrigoGraphAnalyser(eqn2);
+ assertEquals(false, test.canStartAnalyser());
+ }
+
+ @Test
+ void correctStatementsWithValidEqn() {
+ String eqn = "2*cos(2*pi*x+5)+1";
+ TrigoGraph test = new TrigoGraph(eqn);
+ TrigoGraphAnalyser analyser = new TrigoGraphAnalyser(eqn);
+ assertEquals(true, analyser.canStartAnalyser());
+ }
+}
diff --git a/src/test/java/seedu/badmaths/trigograph/TrigoGraphVisualiserTest.java b/src/test/java/seedu/badmaths/trigograph/TrigoGraphVisualiserTest.java
new file mode 100644
index 0000000000..41ed98a7f4
--- /dev/null
+++ b/src/test/java/seedu/badmaths/trigograph/TrigoGraphVisualiserTest.java
@@ -0,0 +1,45 @@
+package seedu.badmaths.trigograph;
+
+import org.junit.jupiter.api.Test;
+import seedu.badmaths.IllegalTodoException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class TrigoGraphVisualiserTest {
+ @Test
+ void eqnWithInvalidTrigoGivesInvalidState() {
+ try {
+ TrigoGraphVisualiser visualiser = new TrigoGraphVisualiser(1.0, 2.5, 1.67,
+ 9, "tann");
+ visualiser.startVisualiser();
+ assertThrows(IllegalTodoException.class, () -> {
+ visualiser.isValidState();
+ });
+ } catch (IllegalTodoException e) {
+ System.out.println("Wrong trigger.");
+ }
+ }
+
+ @Test
+ void eqnWithValidTanGivesValidState() {
+ try {
+ TrigoGraphVisualiser visualiser_tan = new TrigoGraphVisualiser(1.0, 2.5, 1.67,
+ 9, "tan");
+ assertEquals(true, visualiser_tan.isValidState());
+ } catch (IllegalTodoException e) {
+ System.out.println("Wrong trigger.");
+ }
+ }
+
+ @Test
+ void eqnWithValidSinGivesValidState() {
+ try {
+ TrigoGraphVisualiser visualiser_sin = new TrigoGraphVisualiser(1.0, 2.5, 1.67,
+ 9, "sin");
+ assertEquals(true, visualiser_sin.isValidState());
+ } catch (IllegalTodoException e) {
+ System.out.println("Wrong trigger.");
+ }
+ }
+}
diff --git a/src/test/resources/TestNotes.txt b/src/test/resources/TestNotes.txt
new file mode 100644
index 0000000000..eddc3561c1
--- /dev/null
+++ b/src/test/resources/TestNotes.txt
@@ -0,0 +1,3 @@
+HIGH Y 2 Note 1
+LOW N 1 Note 2
+MEDIUM Y 0 Note 3
diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT
index 892cb6cae7..3d040780c6 100644
--- a/text-ui-test/EXPECTED.TXT
+++ b/text-ui-test/EXPECTED.TXT
@@ -1,9 +1,10 @@
-Hello from
- ____ _
-| _ \ _ _| | _____
-| | | | | | | |/ / _ \
-| |_| | |_| | < __/
-|____/ \__,_|_|\_\___|
-What is your name?
-Hello James Gosling
+____ _ __ __ _ _
+| _ \ | | | \/ | | | | |
+| |_) | __ _ __| | | \ / | __ _| |_| |__ ___
+| _ < / _` |/ _` | | |\/| |/ _` | __| '_ \/ __|
+| |_) | (_| | (_| | | | | | (_| | |_| | | \__ \
+|____/ \__,_|\__,_| |_| |_|\__,_|\__|_| |_|___/
+You can type 'Help' to learn what I can do for you :)
+Goodbye!
+----------------------------------------------------------------------
diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt
index f6ec2e9f95..09170083fc 100644
--- a/text-ui-test/input.txt
+++ b/text-ui-test/input.txt
@@ -1 +1 @@
-James Gosling
\ No newline at end of file
+Bye
diff --git a/trigo.JPG b/trigo.JPG
new file mode 100644
index 0000000000..4e8b1992f0
Binary files /dev/null and b/trigo.JPG differ
diff --git a/trigoGraphAnalyser.log b/trigoGraphAnalyser.log
new file mode 100644
index 0000000000..54ca339ca4
--- /dev/null
+++ b/trigoGraphAnalyser.log
@@ -0,0 +1,44 @@
+
+
+
+
+ 2023-04-10T04:51:24.737923200Z
+ 1681102284737
+ 923200
+ 0
+ seedu.badmaths.trigograph.TrigoGraphAnalyser
+ SEVERE
+ seedu.badmaths.trigograph.TrigoGraphAnalyser
+ canStartAnalyser
+ 1
+ ArrayIndexOutOfBounds
+
+ java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
+
+ seedu.badmaths.trigograph.TrigoGraphAnalyser
+ findVerticalShift
+ 192
+
+
+ seedu.badmaths.trigograph.TrigoGraphAnalyser
+ canStartAnalyser
+ 90
+
+
+ seedu.badmaths.trigograph.TrigoGraph
+ startGraphAnalysis
+ 27
+
+
+ seedu.badmaths.Command
+ executeCommand
+ 84
+
+
+ seedu.badmaths.BadMaths
+ main
+ 79
+
+
+
+