-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CS2113-T18-1] Movie Reviews #47
base: master
Are you sure you want to change the base?
Changes from all commits
51fea35
74830be
ac14c92
43ef872
9a02aa0
a48b1da
ab227ef
62f9950
b81d77e
fa8f2bb
9e09080
44063b9
4b27d66
67baeaf
e79e743
2f43c8d
1866147
a93df1f
610cb68
9eae96c
292498f
f88bb9a
e099ef6
03abb3a
bbe9d95
4c628b6
1c66376
c44cffd
3206550
6b8179c
c47a187
f428a6e
224c008
448a26c
32a4b5d
fe22570
2e32dc8
68e3d01
8d6debb
ebcb79d
7b1d960
6a6ce50
1f5b82f
78049bc
8cdc599
ec19de2
fc8a939
4a913b3
9f5b68c
194e3ac
6603f08
65343df
6a7b7cb
63c9b09
0f6b8ea
1548e86
e87d8d2
262137d
7215f1e
0d6a08c
58f69ed
06a8712
8d6a3c9
3348ed4
fa82902
6299d53
2d73ca1
5e4156b
2b67780
39e1d51
5950b49
c1dae71
b093345
47a9e25
65c508d
7ff5be8
493949b
786309f
156a5fb
5d58b0a
4c0f20c
d8c6abb
16d2275
53214f6
78c4a98
7e786c4
b58d5b8
c4bdd18
d43dd57
8313850
518ccb3
60543f2
5dc34aa
195e4c2
35330d8
4c105ec
7fabff6
176c7f9
86087d1
4777bc8
d6740d7
fb93cde
0ca7e71
9f2ace7
f585ae9
cad790c
dc3aaef
6f4f925
174df99
db47c32
1678ef2
6412b92
7e8e428
f41b866
6386728
be2869b
b46cdb4
ec25e5b
2de8fc5
2015cbf
2835e0b
7ddbedd
d239494
db79359
6617fe6
03b5443
5b7555d
28afa0b
24ecfd9
0320a9f
26b7378
cb0e611
fb46062
5785dec
e82e1e4
1849f68
b848989
7e1d563
c59917a
55ae1be
97c7c66
690f34c
f9921f4
801560b
9a1edb3
3dc9890
4683471
ebb6a23
34e5474
6a1753f
ff68605
5e2066e
1dcb993
c4cae0b
246bcc7
fce6d70
28d004e
4d5094d
d97c96e
7218e33
eea41f9
3e88ae2
23f5e61
648306c
82e2642
096198c
1a898a5
fba9c83
1f01ded
13d830b
4b323cf
b5a0f8f
2394d3d
310fbbf
2fee06a
2aa0710
5a2466e
d166d67
3c09325
6a45336
8244407
6b83f9f
b844839
ac827e6
5f781f4
a6dde91
f2d5090
0cb7ddb
5b3aa58
f5e622e
300e1a0
de3a026
5f4dd51
381b6ed
1db580e
6edb5c2
843caf5
a8d1cca
aa96bc0
1b9dfce
7fcc544
e14f6d0
02bbcc1
4cb09cf
b41557b
66059bf
9b88bc7
887e0d3
7ecf7ee
eb04b0b
13359cb
46acddc
4a4a54f
e65eeec
776ea31
3a69fab
f9d522d
37e1df9
19e1fb3
9ab8ff3
0bdc67d
437890e
4ecdfc5
2431f53
1815076
1f7259d
d2efba2
c962c6c
2a0fd62
925902e
8d09bd9
b4cad22
b6487b6
dbc9d81
93ad3e9
c4abf5e
392c265
8e102ad
8a5897e
857b4b5
7c7f5df
9b9ad6b
1d49c6e
4b23e4c
ef6a4b2
59e8440
872e4e3
8a471aa
38c23cf
c7873e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Main-Class: seedu.duke.Duke | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,4 +43,5 @@ checkstyle { | |
|
||
run{ | ||
standardInput = System.in | ||
enableAssertions = true | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
# About us | ||
|
||
Display | Name | Github Profile | Portfolio | ||
--------|:----:|:--------------:|:---------: | ||
![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | ||
![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | ||
![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | ||
![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | ||
![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | ||
| Display | Name | Github Profile | Portfolio | | ||
|-----------------------------------|:-------------------:|:----------------------------------------:|:--------------------------------:| | ||
| ![](imgs/naz019_github_photo.png) | Nazrul Syahmi | [Github](https://github.com/naz019) | [Portfolio](team/naz019.md) | | ||
| ![](imgs/matthewphua.png) | Matthew Phua | [Github](https://github.com/matthewphua) | [Portfolio](team/matthewphua.md) | | ||
| ![](imgs/shaoyong.png) | Ong Shao Yong | [Github](https://github.com/redders7) | [Portfolio](team/redders7.md) | | ||
| ![](imgs/indraneel.png) | Indraneel Paranjape | [Github](https://github.com/indraneelrp) | [Portfolio](team/indraneelrp.md) | | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,235 @@ | ||
# Developer Guide | ||
|
||
## Acknowledgements | ||
## Design & Implementation | ||
|
||
### Ui | ||
The `Ui` class handles user input and basic output messages. It can | ||
* Read user input | ||
* Output various messages to the user | ||
When instantiated, the Ui class holds a protected attribute called isExit, which is a flag for whether the conditions for | ||
termination of the program have been met. In other words, this tracks whether the command entered by the user is the | ||
termination command. The functions in the Ui class help greet the user, get continuous input, and print output to the user. | ||
|
||
{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} | ||
![img.png](imgs/UiClass.png) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that this is non-standard UML notation. You can use the info here to change settings for PlantUML: nus-cs2113-AY2122S1/forum#114 |
||
|
||
## Design & implementation | ||
### Storage Class | ||
The `Storage` class handles the storing and retrieval of users' information. The storage class is instantiated with a | ||
filepath and folderpath string, which represents where the stored.txt file will be created in the /data folder. | ||
The Storage class is instantiated in the Duke constructor. The main program of Duke calls the function from the storage class | ||
whose purpose is to check whether a file exists at the specified path and make the file if there is none. The main function | ||
also calls the loadMedia function from the Storage class, which retrieves the past stored data so that it can be mainpulated | ||
by the user.The saved information is then loaded in to the reviewList object which the user maniuplates. | ||
After every command entered by the user, the storage txt file is updated via the function updateFile. Keeping the file updated after every user command ensures minimal data loss in the case of a non-graceful exit of the program. Moreover, the function loadMedia performs some basic checks to ensure that the format of the lineInput being read in is valid. This minimises | ||
ungraceful termination in case of tampering of the text file. | ||
|
||
{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} | ||
![img.png](imgs/StorageClass.png) | ||
|
||
### Media Classes | ||
![img.png](imgs/MovieClass.png) | ||
|
||
### Commands | ||
The command component enables users to make changes to their review list. The command word is taken from the first word | ||
of the user input, and is processed through the `Parser` class. The class diagram shows how the Commands parent class is | ||
implemented, as well as its extended classes. | ||
![img.png](imgs/CommandsClass.png) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
#### Add | ||
The `add` command enables users to create new movie or TV Show reviews and add them to their review list. The following | ||
is how the `add` command works: | ||
1. The `Parser` class takes in the user input, and parses this by using its `processUserInput` function. | ||
2. If the parsed command word is recognised to be the `add` command, the `executeAdd` function is called. | ||
3. Using the parsed command, `Parser` then determines whether the review to be added is a movie or Tv show. Otherwise, a | ||
DukeException error is thrown. | ||
4. A new variable of type Media parent class, `toAdd`, is then created. The `AddCommand` function is then called to add | ||
the Movie or Tv Show `toAdd` into the review list, `reviewList`. | ||
![img_1.png](imgs/AddCommandSequence.png) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider breaking up the diagram. If showing the sequence of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
#### Find | ||
The find command enables users to search for existing reviews that contains a given keyword. This is done through the | ||
following steps: | ||
1. The `Parser` class takes in the user input, and parses this by using its `processUserInput` function. | ||
2. If the parsed command word is recognised to be the `add` command, the `executeFind` function is called and extracts | ||
the keyword to search for from the user input. | ||
3. `Parser` then creates an `executor` object by creating a new `FindCommand`. `Parser` then calls the `execute` | ||
function from `executor` which loops through all reviews in the list and displays those containing the given keyword | ||
using the `toString()` function found in both the `Movie` and `TvShow` subclasses. | ||
![img.png](imgs/FindCommandSequence.png) | ||
|
||
#### List | ||
The list command outputs all inputted reviews per category: | ||
|
||
1. The list command sequence begins with a `Parser` object. | ||
2. The `Parser` object calls on `executeList` which is responsible for creating a `ListCommand` Object. It then calls on its `execute` method to execute the proper actions. | ||
3. In this `execute` function, it loops through all the stored reviews and separates each review based on category and formats using the proper `toString` method. | ||
4. Finally, an output string is returned and the `Parser` class calls on the `UI` object to print the output to the user. | ||
|
||
![img.png](imgs/ListCommandSequence.png) | ||
|
||
#### Sort | ||
The sort command sorts reviews based on a given input. | ||
|
||
1. The sort command sequence begins with a `Parser` object. | ||
2. The `Parser` object calls on `executeSort` which is responsible for creating a `SortCommand` Object. Then it calls on `SortCommands`'s `execute` method to execute the proper actions. | ||
3. The `execute` method sorts the review list by the given field. When sorting by rating or date, the sorting is done in | ||
reverse order while whereas when sorting by title or genre, the sorting is done in default order. | ||
4. The `execute` function returns the sorted outputted string. | ||
5. Finally, the `Parser` class calls on the `UI` object to print out the output to the user. | ||
|
||
![img.png](imgs/sortSequence.png) | ||
|
||
#### Remove | ||
When the user wants to delete a specific review from the review list, they will use the following command: "delete | ||
[mediaType] [index]" which triggers the executeDelete() method in Parser. For example, "delete movie 2" will delete the | ||
review at index 2 of movie section of the review list. | ||
|
||
1. To check that the command given by the user is valid, the program checks for the condition that the user input | ||
array contains exactly three String objects, failing which a DukeException will be thrown. | ||
|
||
2. The program then checks if a valid media type is given i.e. "movie" or "tv", failing which a DukeException will | ||
also be thrown. | ||
|
||
3. If the previous conditions are successfully met, a RemoveCommand object is created and its execute() method is | ||
called. This method loops through the review list, first checking whether the review is of the given media type, then | ||
whether the review is at the given index. | ||
|
||
4. If both conditions are met, the review is successfully removed from the review list. | ||
|
||
5. A string confirming the successful removal of the review is generated and printed for the user. | ||
|
||
![img.png](imgs/deleteSequence.png) | ||
|
||
#### Clearing the review list | ||
|
||
When the user wants to remove every review from the review list, they will use the following command: "clear", which | ||
triggers the executeClear() method in Parser. | ||
|
||
1. A ClearCommand object is created and its execute() method is called. | ||
|
||
2. The ArrayList method clear() is called on the review list, removing every Media object from the review list. | ||
|
||
3. A string confirming the successful clearing of the review list is generated and printed for the user. | ||
|
||
![img.png](imgs/clearSequence.png) | ||
|
||
### Marking favourite reviews or listing all favourites | ||
|
||
The "favourite" command covers two user scenarios: | ||
1) The user wants to mark or unmark a specific review as favourite. | ||
2) The user wants to list all favourites. | ||
|
||
**Scenario 1**: | ||
To mark or unmark a review, the user will use the following command: "favourite [type] [index]", which triggers the | ||
executeFavourite() method in Parser. For example, "favourite 3" mark the review at index 3 if it has not been marked as | ||
favourite, or unmark it if it has already been marked as favourite. | ||
|
||
Step 1: A FavouriteCommand object is created and its execute() method is called. | ||
|
||
Step 2: The program checks that a valid media type is given in the user input i.e. "movie" or "tv" failing which a | ||
DukeException will be thrown. | ||
|
||
Step 3: The program then loops through the review list to check whether the review is of the given media type and at | ||
the given index. | ||
|
||
Step 4: If the review at the given index has not been marked as favourite, the setFavourite(true) method of the Media | ||
class is called to mark the review as favourite. Conversely, if the review at the given index has already been marked | ||
as favourite, the setFavourite(false) method of the Media class is called to unmark the review as favourite. | ||
|
||
Step 5: A string confirming the successful marking or unmarking of the review as favourite is generated and printed for | ||
the user. | ||
|
||
**Scenario 2**: | ||
To list all favourites in the review list, the user will use the following command: "favourite list", which triggers | ||
the executeFavourite() command in Parser. | ||
|
||
Step 1: A FavouriteCommand object is created and its execute() method is called. | ||
|
||
Step 2: The program checks that the user input contains the "list" keyword. | ||
|
||
Step 3: The program loops through the review list and checks whether the review has been marked as favourite. If the | ||
review has been marked as favourite, the toString() method of the Media class is called on that review so that the | ||
stringified version of that review can be added to a String object, which will be returned to the Parser. | ||
|
||
Step 4: The String object which was returned to the Parser and contains the list of reviews marked as favourite is | ||
printed for the user. | ||
|
||
![img.png](imgs/favouriteSequence.png) | ||
|
||
|
||
## Product scope | ||
### Target user profile | ||
|
||
{Describe the target user profile} | ||
myReviews targets individuals who are avid movie or TV show watchers and are proficient in using the command line. | ||
|
||
### Value proposition | ||
|
||
{Describe the value proposition: what problem does it solve?} | ||
For movie and TV show enthusiasts, using common movie review websites like RottenTomatoes involves navigating past a | ||
lot of irrelevant pages to arrive at a review page. Users who want to submit personal reviews may also have to spend up | ||
to a minute navigating these websites first. Furthermore, there is often no convenient way for users to view and compare | ||
their personal reviews for any form of analysis. Hence, myReviews aims to provide a fast and bloat-free all-in-one | ||
avenue where users can quickly store their personal reviews and view them at a glance. | ||
|
||
## 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|user| add movies to a list | keep track of which movies I have watched. | | ||
|v1.0|user| add ratings out of 10 to a movie | remember how much I enjoyed the movie. | | ||
|v1.0|user| remove movies from my list | delete erroneous entries. | | ||
|v1.0|user| list the movies I have added | view what movies I have watched | | ||
|v1.0|user| enter the date I watched the movie | recall when I watched the movie. | | ||
|v2.0|user| arrange my review list by worst or best ratings | see the shows that I like or hate the most. | | ||
|v2.0|user| star/favorite a movie | mark shows that I would like to watch again. | | ||
|v2.0|user| star/favorite a tv show | mark tv shows that I may want to watch again. | | ||
|v2.0|user| see a display of my favourited items | I can quickly refer to the shows I have marked. | | ||
|v2.0|user| be able to save my information after I exit the program | offload it from my mind. | | ||
|v2.0|user| be able to retrieve my last saved list | I do not have to remember it myself. | | ||
|v2.0|user| list the movies I have watched | view what movies I have watched | | ||
|v2.0|user| list the tv shows I have watched | view what tv shows I have watched | | ||
|v2.0|user| search movies using a keyword | to find a specific movie I have watched | | ||
|v2.0|user| search tv show using a keyword | to find a specific tv show I have watched | | ||
|v2.0|user| clear movies that I have watched | to clear my watch history | | ||
|v2.0|user| clear tv shows that I have watched | to clear my watch history | | ||
|v2.0|user| automatically save reviews | load my previously added reviews upon restarting program | | ||
|
||
|
||
|
||
## Non-Functional Requirements | ||
|
||
{Give non-functional requirements} | ||
1. Performance: The program should respond within 2 seconds of user input. | ||
2. Quality: With guidance by the user guide, a new user should be able to navigate the program. | ||
3. Technical: The program should work with all environments that load the program with Java 11. | ||
4. Project Scope: The program is only required to handle reviews for movies and tv shows. | ||
|
||
## Glossary | ||
|
||
* *glossary item* - Definition | ||
* *review* - The user's appraisal of a movie or TV show, reflected in a rating. | ||
|
||
## 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} | ||
Set Up: | ||
1. Ensure that you have Java 11 or above installed. | ||
2. Download the latest version of `myReviews` from [here](https://github.com/AY2223S1-CS2113-T18-1b/tp/releases). | ||
3. Copy the jar file into the folder you want to store your reviews. | ||
4. Open terminal application and change directory to the above folder. | ||
5. Run the jar file by entering java -jar myReviews.jar into the terminal. | ||
|
||
Testing: | ||
1. myReviews will display a greeting message. Enter a command and press Enter to execute it. | ||
2. Add a Movie or TvShow: | ||
|
||
`add /movie <title> /rating <rating> /date <dateWatched> /genre <genre>` | ||
|
||
`add /tv <title> /rating <rating> /date <dateWatched> /genre <genre> /site <location>` | ||
3. Input additional commands for testing | ||
(refer to user guide for command parameters): | ||
1. `list` | ||
2. `sort` | ||
3. `favourite` | ||
4. `favourite list` | ||
5. `find` | ||
6. `delete` | ||
7. `clear` | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
@startuml | ||
!include style.puml | ||
|
||
class "{abstract} \nCommands" { | ||
String execute() | ||
} | ||
hide "{abstract} \nCommands" fields | ||
|
||
class AddCommand { | ||
+media: Media | ||
+AddCommand(reviews: ReviewList, media: Media) | ||
} | ||
|
||
class ClearCommand { | ||
+ClearCommand(reviews: ReviewList) | ||
} | ||
hide ClearCommand fields | ||
|
||
class FavouriteCommand { | ||
+userInput: String[] | ||
+FavouriteCommand(reviews: ReviewList, userInput: String[]) | ||
} | ||
|
||
class FindCommand { | ||
-outputString: String | ||
-movieString: String | ||
-tvShowString: String | ||
-listDelimiter: String | ||
#searchTerm: String | ||
+FindCommand(reviews: ReviewList, searchTerm: String) | ||
} | ||
|
||
class ListCommand { | ||
-outputString: String | ||
-movieString: String | ||
-tvShowString: String | ||
-listDelimiter: String | ||
+ListCommand((reviews: ReviewList) | ||
} | ||
|
||
class RemoveCommand { | ||
+index: int | ||
+RemoveCommand(reviews: ReviewList, index: int) | ||
} | ||
|
||
class SortCommand { | ||
+userInput: String[] | ||
+SortCommand(reviews: ReviewList, userInput: String[]) | ||
} | ||
|
||
class ReviewList { | ||
+inputs: ArrayList<Media> | ||
+void add(media: Media) | ||
+void remove(index: int) | ||
+String toString() | ||
} | ||
|
||
"{abstract} \nCommands" -up-> "1" ReviewList : > uses | ||
|
||
skinparam groupInheritance 1 | ||
|
||
"{abstract} \nCommands" <|-right- AddCommand | ||
"{abstract} \nCommands" <|-right- ClearCommand | ||
"{abstract} \nCommands" <|-- FavouriteCommand | ||
|
||
"{abstract} \nCommands" <|-- FindCommand | ||
"{abstract} \nCommands" <|-- ListCommand | ||
"{abstract} \nCommands" <|-left- RemoveCommand | ||
"{abstract} \nCommands" <|-left- SortCommand | ||
|
||
|
||
@enduml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Media class is shown as abstract in the UML diagram. However, it is not implemented as an abstract class. Is it supposed to be just shown as 'normal' class in the UML diagram?