-
Notifications
You must be signed in to change notification settings - Fork 231
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-F15-4] BookBuddy #54
base: master
Are you sure you want to change the base?
Changes from 237 commits
710ffae
b96b434
7b035be
84adc3c
de13d71
3a3fc92
ed5e560
9412bb1
ec569b3
4b1f6d9
0609e25
d027b8f
1c787a4
9a0e416
27e46ca
f30228c
c0194a2
9c47da6
63ffe2d
428e620
d73c73c
bf0a3ea
0526880
fd72967
1b6a222
9ada02d
e5c0a5c
73bb92d
b71fd50
456c954
97f9875
861e712
5fa73e6
f08aa61
516797b
07002fc
3ef2737
b238ed1
cae51b9
68c9344
df7ae15
a1840d0
e82d270
a512908
90c9aae
ba52217
e93069d
26e84cf
780b896
ba647d8
2c78698
55e1268
9b2ab9c
3858f9f
add2227
56345d5
cf3daab
d7e92ad
7c4477f
34a8243
49d219a
6c1bbd5
a1786c9
db5f12a
32f516b
0d17ef0
11ec90c
d4dbd0a
0edcddd
ef92ceb
04f8aa4
e469438
a5e0f9a
0068a36
3e787fe
ae844d6
c9e4191
21d8e28
2601b0e
6c0edaa
f2a0828
2f4958c
dd5b2d6
efdff81
beff5a6
0d3d4f5
b361ce6
925208b
66dfae5
1678a54
955f809
eeb669b
38ee255
e38893b
9b85f94
6ee9ecf
42af33b
d7ed909
2855eaf
bb3302f
17d3a48
a47ef27
1ae9490
264917b
f666bd6
9427462
88bafb9
85274a1
688503c
0d39ad8
6833b5e
bb45824
87060d0
dffe06e
ad0f9ec
3358171
e0d1899
ba3f7d5
62ae195
a487345
88bc37e
2a7af01
f4d2568
08eb0d2
8dd8f05
cff2977
43d9261
3c91489
ebd04d4
68af54f
4e08a33
36a2fc4
cf9dc87
c333b14
6e48fef
92a7e1f
a7835ea
0aa462b
c5082dc
8cccf6b
79d8aeb
932c633
72c68bf
ebf9b86
8559dee
6463a01
5cf817e
d5924d8
61a1891
b9e8c4c
107ecf5
8384f7e
1416bed
0d34f56
3651acc
a0049c9
2142474
2717594
dd5ae54
45cd16a
44ca3a9
f66375c
0ba1a36
c8c63de
04b28cc
12e624b
136b5eb
9c46538
02fddf2
9fb9833
28e1199
63975a9
667c9d8
b513ee2
2533bcb
3da37aa
109ccf0
6e58f53
5188332
3c7c0e2
cc761d9
403bc58
1dd2c99
e703274
69975db
cfd1585
49c7f48
ea5d2be
557fd42
7f236e8
0ba2be9
370caac
24fe1ec
7b274bf
37f6238
94c732e
712c2d1
dfb7676
506aa0e
64ca366
9da2be0
3848b30
81b9039
86d816a
a80d49a
8c8da3e
b1e0630
6b0cb79
4bef2e7
5d8a3c9
7a8d578
d280ed7
4bf529b
b8abbe3
ca5e9cf
932c875
1d750b2
fcfcb12
3af4592
9c10219
e224239
b8911ff
cd7d18f
df95894
8d3c479
6db89d7
9a02c5e
55920fa
936c109
4145f9e
f09e119
8b8d0d5
9f3e950
2f83c33
2e2a319
4531ae6
fc2e81f
37be28c
14aba18
0f94ae2
6f95e4d
0d9a1b1
bc88e68
0c0481e
f0ed1ef
9801dbf
344520f
3ef2f65
468cb72
d822274
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,20 @@ | ||
Apr 01, 2024 6:16:13 PM seedu.bookbuddy.BookBuddy main | ||
INFO: BookBuddy application started. | ||
Apr 01, 2024 6:16:13 PM seedu.bookbuddy.BookBuddy getUserInput | ||
INFO: Starting to get user input. | ||
Apr 01, 2024 6:20:29 PM seedu.bookbuddy.BookBuddy main | ||
INFO: BookBuddy application started. | ||
Apr 01, 2024 6:20:29 PM seedu.bookbuddy.BookBuddy getUserInput | ||
INFO: Starting to get user input. | ||
Apr 03, 2024 12:51:38 PM seedu.bookbuddy.BookBuddy main | ||
INFO: BookBuddy application started. | ||
Apr 03, 2024 12:51:38 PM seedu.bookbuddy.BookBuddy getUserInput | ||
INFO: Starting to get user input. | ||
Apr 03, 2024 12:57:30 PM seedu.bookbuddy.parser.parservalidation.Exceptions validateCommandArguments | ||
WARNING: The add Command requires a book title | ||
Apr 03, 2024 12:57:30 PM seedu.bookbuddy.parser.parservalidation.Exceptions handleException | ||
WARNING: Invalid command argument: The add Command requires a book title | ||
Apr 03, 2024 12:57:30 PM seedu.bookbuddy.parser.ParserMain parseCommand | ||
WARNING: Sorry but that is not a valid command. Please try again | ||
Apr 03, 2024 12:57:30 PM seedu.bookbuddy.parser.parservalidation.Exceptions handleException | ||
WARNING: Command is invalid: Sorry but that is not a valid command. Please try again or type: help |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
# 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 | ||
--------|:-------:|:---------------------------------------:|:---------: | ||
![](https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.nationalgeographic.com%2Fanimals%2Fmammals%2Ffacts%2Fdomestic-cat&psig=AOvVaw0h1oKdH4MW00nu2-jCVMT5&ust=1709970657610000&source=images&cd=vfe&opi=89978449&ved=0CBMQjRxqFwoTCOj10J6X5IQDFQAAAAAdAAAAABAI) | Joy Liu | [Github](https://github.com/liuzehui03) | [Portfolio](docs/team/johndoe.md) | ||
![](https://via.placeholder.com/100.png?text=Photo) | Joshua Ho | [Github](https://github.com/joshuahoky) | [Portfolio](docs/team/johndoe.md) | ||
![](https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.thesprucepets.com%2Fabout-tuxedo-cats-554695&psig=AOvVaw0C_GqS3DVZWNcXkFONc6FM&ust=1709970666751000&source=images&cd=vfe&opi=89978449&ved=0CBMQjRxqFwoTCNi3kqOX5IQDFQAAAAAdAAAAABAE) | GARETH Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | ||
![](https://via.placeholder.com/100.png?text=Photo) | Zong Yao | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,194 @@ | ||
# Developer Guide | ||
|
||
## Table of Contents | ||
* [Acknowledgements](#acknowledgements) | ||
* [Design & Implementation](#design--implementation) | ||
* * [Categorising the different books by their genres](#categorising-the-different-books-by-their-genres) | ||
* * [BookList Class Component](#booklist-class-component) | ||
* * [ParserMain Class Component](#parsermain-class-component) | ||
* * [FileStorage Class Component](#filestorage-class-component) | ||
* [Product Scope](#product-scope) | ||
* * [Target user profile](#target-user-profile) | ||
* * [Value proposition](#value-proposition) | ||
* [User Stories](#user-stories) | ||
|
||
## Acknowledgements | ||
|
||
{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} | ||
|
||
Reference to AB-3 Developer Guide | ||
* [Source URL](https://se-education.org/addressbook-level3/DeveloperGuide.html#documentation-logging-testing-configuration-dev-ops) | ||
* Used as template to structure this DeveloperGuide | ||
* Reference to AB-3 diagrams code | ||
|
||
Reference to AB-3 diagrams code | ||
* [Source URL](https://github.com/se-edu/addressbook-level3/tree/master/docs/diagrams) | ||
* Used as reference to understand PlantUML syntax | ||
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. I like how you give credit to the sources you referenced! |
||
|
||
## Design & implementation | ||
|
||
{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} | ||
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. Perhaps you could remove the placeholder text so that it's clearer where the Design and Implementation section begins |
||
|
||
### Categorising the different books by their genres | ||
This functionality enables the categorization of books into distinct groups based on their genres, facilitating better | ||
organization and tracking. The implementation of this feature involves interactions across multiple classes within the | ||
system. | ||
|
||
#### Overview | ||
The process of categorizing books by genre is a multistep operation that involves the following classes: | ||
1. `ParserGenre`: This class contains methods that handle the categorization of books. | ||
2. `BookGenre`: Individual book objects are updated with their respective genres directly in this class. | ||
3. `ParserMain`: This class is responsible for parsing the input command to extract the specific index and genre. | ||
|
||
#### Architecture-Level Design: | ||
|
||
- The book management system is structured using a layered architecture model, comprising the UI layer, the command | ||
parser layer, and the data model layer. | ||
- The `set-genre` feature is primarily situated in the command parser layer but interacts closely with the data model | ||
layer to update the genre of a book. | ||
|
||
#### Component-Level Design: | ||
|
||
- `UI Layer`: Receives input from the user and displays the results of operations. It's where the user's request to set | ||
a genre starts and ends with feedback. | ||
- `ParserMain` (Command Parser Layer): Acts as the central hub for command processing, determining the type of command | ||
and delegating to the specific parser. | ||
- `ParserGenre` (Command Parser Layer): Specializes in handling the set-genre command. It prompts the user for inputs | ||
and validates them. | ||
- `BookList` (Data Model Layer): Maintains the list of books and genres. It's queried to ensure the book index is valid | ||
and to retrieve or update the list of genres. | ||
- `BookGenre` (Data Model Layer): Provides the functionality to set the genre of a book in the `BookList`. | ||
|
||
#### Implementation Details: | ||
|
||
- Upon invoking the `set-genre` command, `ParserMain` interprets the command and forwards it to `ParserGenre`. | ||
`ParserGenre` then guides the user through selecting an existing genre or adding a new one, ensuring valid inputs at | ||
each step. | ||
- The chosen genre is then applied to the specified book through `BookGenre`, which interfaces with `BookList` to make | ||
the update. | ||
- Throughout this process, `Ui` is called upon to display messages, guiding the user and confirming the successful | ||
update. | ||
|
||
#### Rationale for Design: | ||
|
||
- The command pattern used allows for easy addition of new commands and features without altering existing code | ||
structures, adhering to open/closed principles. | ||
- The clear separation of concerns makes the system robust, with each component focusing on a single responsibility, | ||
enhancing maintainability and scalability. | ||
|
||
#### Alternatives Considered: | ||
|
||
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. Good display of alternatives considered! |
||
- An embedded approach, where genre setting logic is part of a larger class managing all book attributes, was | ||
considered. However, this was rejected due to potential scalability issues and difficulty in maintaining code. | ||
|
||
![SetGenreSequenceDiagram.png](UML_diagrams/SetGenreSequenceDiagram.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. |
||
|
||
### BookList Class Component | ||
The `BookList` class is responsible for all actions involving the list of books that the user has. | ||
|
||
#### Overview | ||
|
||
The `BookList` class contains one protected static ArrayList named books. This ArrayList will contain Book objects. The methods in | ||
The `BookList` class contains one protected static ArrayList named books. This ArrayList will contain Book objects. | ||
The methods in this class all change the ArrayList according to the command given. | ||
|
||
#### Detailed Workflow | ||
Apart from the constructor, the methods of this class like getSize(), addBook() all either return a piece of | ||
information about the ArrayList, | ||
the book object that is selected or change an attribute of the ArrayList or selected book object. For the | ||
printAllBooks() method, the ArrayList | ||
is iterated through, with the details of each book being printed out according to the toString() format of each book. | ||
Other than that, methods like | ||
markDoneByIndex() and markUndoneByIndex() both will change the isRead() attribute of the book of the given index. This | ||
class handles errors related to the | ||
ArrayList, throwing exceptions for invalid indexes and invalid actions based on current state (if trying to mark a book | ||
that is already read). | ||
|
||
#### Implementation and Rationale | ||
|
||
### ParserMain Class Component | ||
The `ParserMain` class is responsible for parsing any input from the user and making sense of them to execute the correct commands. | ||
|
||
#### Overview | ||
By importing predefined string constants from `CommandList` class representing the valid commands, the `ParserMain` class | ||
parses the input from a user using the `parseCommand` method. The class diagram below shows how `ParserMain` interacts with other | ||
classes. | ||
![ParserMain.png](UML_diagrams/ParserMain.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. |
||
|
||
#### Detailed Workflow | ||
Whenever input from the user is detected by the program, the `ParserMain` class will split the command into 2 parts, with the first part | ||
containing the command and the second containing details of the command (if present). The command entered is then evaluated using a | ||
switch statement, with the value of it being compared to the values of each case. In the case of a match, the `ParserMain` class will then | ||
execute the respective action associated with that command by calling other classes from the program such as `BookDisplay` or `ParserAdd`. | ||
This class also handles errors and exceptions associated with the users input. For example, if the user were to give the command `mark` without | ||
specifying an index for which book to mark, or gives a negative number, an appropriate error message will be shown and the command will be rendered | ||
invalid. | ||
|
||
The sequence diagram below shows how user input is processed to carry out the add book command. | ||
![AddCommand.png](UML_diagrams/AddCommand.png) | ||
|
||
#### Implementation and Rationale | ||
The `ParserMain` class incorporates exception handling to detect invalid or unrecognized commands. This allows the program to continue running | ||
while prompting the user for valid input | ||
|
||
By abstracting out the parsing functionality of BookBuddy into a separate `ParserMain` class, the complexity of parsing | ||
user input is removed from the main code. It is instead replaced by a simple interface for the user to work with, adhering to the abstraction | ||
concept of object-oriented programming. | ||
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. Good application of OOP concepts! |
||
|
||
### FileStorage Class Component | ||
The `FileStorage` class is crucial for managing file operations in BookBuddy, such as reading from and writing to files, | ||
thereby ensuring data is saved for future sessions. | ||
|
||
#### Overview | ||
The `FileStorage` class interacts with the `BookList` and `BookListModifier` classes to load and save book data. It ensures that | ||
the data directory and file exist upon initialization and provides methods for reading from and writing to the data file. | ||
The class diagram below illustrates the relationship between `FileStorage` and other classes. | ||
|
||
![FileStorage.png](UML_diagrams/FileStorage.png) | ||
|
||
#### Detailed Workflow | ||
Upon instantiation, the `FileStorage` class checks for the existence of a predefined directory (./data) and file (books.txt), | ||
creating them if they do not exist. Existing data, if any, is read from the file and BookBuddy's BookList is initialized | ||
with this data. For reading data, it scans each line of the file, converting each line of text into instances of `Book` with | ||
the appropriate details. For saving data, it iterates through the BookList, converting each book into a string format suitable | ||
for file storage and writes this to the file. | ||
|
||
#### Implementation and Rationale | ||
The creation of the `FileStorage` class ensures that all features related to reading and writing data is taken away from other | ||
parts of the application. This separation makes the `FileStorage` class solely responsible for these features, adhering to | ||
the Single Responsibility Principle. | ||
|
||
## Product scope | ||
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. |
||
### Target user profile | ||
|
||
{Describe the target user profile} | ||
Users that want an all-in-one app to track the books read, progress for each book. | ||
Progress for each book can be recorded according to the number of pages read. | ||
Users will be able to sort books according to genre. | ||
Users can sort books according to Read or Unread. | ||
Users will also be able to search for books via keywords in book titles | ||
|
||
### Value proposition | ||
|
||
{Describe the value proposition: what problem does it solve?} | ||
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. Perhaps you could add a value proposition so that developers can understand at a glance what your program can offer. |
||
|
||
## 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 | new user | see usage instructions | refer to them when I forget how to use the application | | ||
| v1.0 | user | add books to a list | | | ||
| v1.0 | user | remove books from a list | | | ||
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. Perhaps you could add the part for "so that I can" to make it complete. |
||
| v1.0 | user | see the list of books that are read or unread | I can keep track of my reading progress | | ||
| v1.0 | user | change the status of a book | mark a book when I have finished reading it | | ||
| v2.0 | user | add a summary to a book | remember what the book is about | | ||
| v2.0 | user | provide a label for a book | provide my own personal thoughts on the book | | ||
| v2.0 | user | provide a genre for a book | categorise books according to their genre | | ||
| v2.0 | user | provide a rating for a book | know whether a book was good or not | | ||
| v2.0 | user | sort books by their rating | recall which are the best books that I have read | | ||
| v2.0 | user | view all information about a book | remember to add missing information (if any) | | ||
| v2.0 | user | search for books according to keywords | find a book quickly without going through the entire list | | ||
| v2.0 | user | filter books by genre | see all the books in a particular genre | | ||
|
||
|
||
## Non-Functional Requirements | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Duke | ||
# BookBuddy | ||
|
||
{Give product intro here} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
@startuml | ||
|
||
User -> Parser : parseCommand(input, books) | ||
activate Parser | ||
|
||
alt input is ADD_COMMAND | ||
Parser -> ParserAdd : executeParseAdd(books, inputArray) | ||
activate ParserAdd | ||
ParserAdd --> Parser : CommandExecuted | ||
deactivate ParserAdd | ||
alt other commands | ||
Parser -> Parser : handleOtherCommands() | ||
else unsupported command | ||
Parser -> Exceptions : handleException(e, command, inputArray) | ||
activate Exceptions | ||
Exceptions --> Parser : ExceptionHandled | ||
deactivate Exceptions | ||
end | ||
|
||
Parser --> User : getUserInput(books) | ||
deactivate Parser | ||
@enduml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
@startuml | ||
class FileStorage { | ||
- FILE_NAME : String = "books.txt" | ||
- FILE_DIRECTORY : String = "./data" | ||
- FILE_PATH : String = FILE_DIRECTORY + '/' + FILE_NAME | ||
|
||
+FileStorage(books : BookList) | ||
+readData(books : BookList, file : File) : void | ||
+saveData(books : BookList) : void | ||
} | ||
|
||
class BookList { | ||
} | ||
|
||
class BookListModifier { | ||
+addBookFromFile(books : BookList, line : String) : void | ||
} | ||
|
||
FileStorage --> BookList : uses | ||
FileStorage --> BookListModifier : uses | ||
@enduml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
@startuml | ||
scale 2000 * 1500 | ||
left to right direction | ||
class ParserMain { | ||
+parseCommand(input : String, books : BookList) : void | ||
} | ||
|
||
class ParserCommands { | ||
+execute(books : BookList, inputArray : String[]) : void | ||
} | ||
|
||
class BookList { | ||
- static availableGenres : List<String> | ||
- books : ArrayList<BookMain> | ||
+BookList() | ||
+getAvailableGenres() : List<String> | ||
+getBooks() : List<BookMain> | ||
+getSize() : int | ||
+getBook(index : int) : BookMain | ||
} | ||
|
||
class BookDisplay { | ||
+printAllBooks(books : BookList) : void | ||
} | ||
|
||
class Ui { | ||
+helpMessage() : void | ||
} | ||
|
||
class Exceptions { | ||
{static} +validateCommandArguments(inputArray : String[], requiredArgs : int, errorMessage : String) : void | ||
{static} +handleException(e : Exception, command : String, inputArray : String[]) : void | ||
} | ||
|
||
class BookRating { | ||
+printBooksByRating(books : BookList) : void | ||
} | ||
|
||
class CommandList { | ||
{static} ADD_COMMAND : String = "add" | ||
} | ||
|
||
ParserMain --> ParserCommands : uses | ||
ParserMain --> BookList | ||
ParserMain --> BookDisplay : uses | ||
ParserMain --> Ui : uses | ||
ParserMain --> Exceptions : uses | ||
ParserMain --> BookRating : uses | ||
ParserMain --> CommandList : uses | ||
@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.
Good use of a Table of Contents to allow easy navigation of the DG!