By: Team W09-1      Since: Feb 2019      Licence: MIT
- 1. Introduction
 - 2. Setting up
 - 3. Design
 - 4. Implementation
- 4.1. Adding a homework: 
add-hw - 4.2. Delete homework feature
 - 4.3. Edit homework feature
 - 4.4. Find module feature
 - 4.5. Adding a note : 
add-note - 4.6. Deleting a note : 
delete-note - 4.7. Editing and Saving a note : 
edit-notesave-note - 4.8. Editing a Cap Entry : 
edit-cap - 4.9. Deleting a Cap Entry : 
delete-cap - 4.10. Logging
 - 4.11. Configuration
 
 - 4.1. Adding a homework: 
 - 5. Documentation
 - 6. Testing
 - 7. Dev Ops
 - Appendix A: Product Scope
 - Appendix B: User Stories
 - Appendix C: Use Cases
 - Appendix D: Non Functional Requirements
 - Appendix E: Glossary
 - Appendix F: Product Survey
 - Appendix G: Instructions for Manual Testing
- G.1. Launch and Shutdown
 - G.2. Opening a manager
 - G.3. Adding a homework
 - G.4. Deleting a homework entry
 - G.5. Editing a homework entry
 - G.6. Finding homework entries of which contains this module
 - G.7. List all homework entries
 - G.8. Adding a note
 - G.9. Deleting a note
 - G.10. Editing a Note
 - G.11. Saving a Note
 - G.12. Adding a cap entry
 - G.13. Deleting a cap entry
 - G.14. Editing a cap entry
 
 
1. Introduction
Welcome to UltiStudent! UltiStudent is a student application that effectively tackles the problem of having too many applications to manage their school life. To improve the quality of student life in computing, UltiStudent provides a centralised platform for them to manage their homework, cumulative average point and notes. UltiStudent is a desktop-based application intended for students.
This Developer Guide is written for anyone who wishes to contribute to our project. In here, you will find information to help you to set up our project and information to help you understand the architecture behind UltiStudent and how our key features work.
If you would like to help to improve this project by contributing, do contact us for more information!
1.1. Callouts & Symbols
Before proceeding, do refer to the below callout signs that will be used across this document. Familiarising yourself with them will definitely prove to be helpful.
| This callout shares note-worthy information with you. Do read them for a better understanding of the document. | 
| This callout shares helpful tips with you. Not to worry, tips can be good to know but are not vital. Information found here are additional and can prove to be handy for you. | 
| This callout indicates that there is worth being cautioned of. You are encouraged to the read information in here. If you are not careful, you may encounter problems. | 
2. Setting up
Do follow the instructions in order to set up our project on your device.
2.1. Prerequisites
- 
JDK
9or laterJDK 10on Windows will fail to run tests in headless mode due to a JavaFX bug. Windows developers are highly recommended to use JDK9. - 
IntelliJ IDE
IntelliJ by default has Gradle and JavaFx plugins installed. 
Do not disable them. If you have disabled them, go toFile>Settings>Pluginsto re-enable them. 
2.2. Setting up the project in your computer
- 
Fork this repo, and clone the fork to your computer
 - 
Open IntelliJ (if you are not in the welcome screen, click
File>Close Projectto close the existing project dialog first) - 
Set up the correct JDK version for Gradle
- 
Click
Configure>Project Defaults>Project Structure - 
Click
New…and find the directory of the JDK 
 - 
 - 
Click
Import Project - 
Locate the
build.gradlefile and select it. ClickOK - 
Click
Open as Project - 
Click
OKto accept the default settings - 
Open a console and run the command
gradlew processResources(Mac/Linux:./gradlew processResources). It should finish with theBUILD SUCCESSFULmessage.
This will generate all resources required by the application and tests. - 
Open
MainWindow.javaand check for any code errors- 
Due to an ongoing issue with some of the newer versions of IntelliJ, code errors may be detected even if the project can be built and run successfully
 - 
To resolve this, place your cursor over any of the code section highlighted in red. Press ALT+ENTER, and select
Add '--add-modules=…' to module compiler optionsfor each error 
 - 
 - 
Repeat this for the test folder as well (e.g. check
HelpWindowTest.javafor code errors, and if so, resolve it the same way) 
2.3. Verifying the setup
- 
Run the
seedu.ultistudent.MainAppand try a few commands - 
Run the tests to ensure they all pass.
 
2.4. Configurations to do before writing code
2.4.1. Configuring the coding style
This project follows oss-generic coding standards. IntelliJ’s default style is mostly compliant with ours but it uses a different import order from ours. To rectify,
- 
Go to
File>Settings…(Windows/Linux), orIntelliJ IDEA>Preferences…(macOS) - 
Select
Editor>Code Style>Java - 
Click on the
Importstab to set the order- 
For
Class count to use import with '*'andNames count to use static import with '*': Set to999to prevent IntelliJ from contracting the import statements - 
For
Import Layout: The order isimport static all other imports,import java.*,import javax.*,import org.*,import com.*,import all other imports. Add a<blank line>between eachimport 
 - 
 
Optionally, you can follow the UsingCheckstyle.adoc document to configure Intellij to check style-compliance as you write code.
2.4.2. Setting up CI
Set up Travis to perform Continuous Integration (CI) for your fork. See UsingTravis.adoc to learn how to set it up.
After setting up Travis, you can optionally set up coverage reporting for your team fork (see UsingCoveralls.adoc).
| Coverage reporting could be useful for a team repository that hosts the final version but it is not that useful for your personal fork. | 
Optionally, you can set up AppVeyor as a second CI (see UsingAppVeyor.adoc).
| Having both Travis and AppVeyor ensures your App works on both Unix-based platforms and Windows-based platforms (Travis is Unix-based and AppVeyor is Windows-based) | 
2.4.3. Getting started with coding
When you are ready to start coding,
- 
Get some sense of the overall design by reading Section 3.1, “Architecture”.
 - 
Take a look at [GetStartedProgramming].
 
3. Design
3.1. Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
The .pptx files used to create diagrams in this document can be found in the diagrams folder. To update a diagram, modify the diagram in the pptx file, select the objects of the diagram, and choose Save as picture.
 | 
Main has only one class called MainApp. It is responsible for,
- 
At app launch: Initializes the components in the correct sequence, and connects them up with each other.
 - 
At shut down: Shuts down the components and invokes cleanup method where necessary.
 
Commons represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
- 
LogsCenter: Used by many classes to write log messages to the App’s log file. 
The rest of the App consists of four components.
Each of the four components
- 
Defines its API in an
interfacewith the same name as the Component. - 
Exposes its functionality using a
{Component Name}Managerclass. 
For example, the Logic component (see the class diagram given below) defines it’s API in the Logic.java interface and exposes its functionality using the LogicManager.java class.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1.
delete 1 commandThe sections below give more details of each component.
3.2. UI component
API : Ui.java
The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, PersonListPanel, StatusBarFooter, BrowserPanel etc. All these, including the MainWindow, inherit from the abstract UiPart class.
The UI component uses JavaFx UI framework. The layout of these UI parts are
 defined in matching .fxml files that are in the src/main/resources/view
 folder. For example, the layout of the
 MainWindow
 is specified in MainWindow.fxml
The UI component,
- 
Executes user commands using the
Logiccomponent. - 
Listens for changes to
Modeldata so that the UI can be updated with the modified data. 
3.3. Logic component
API :
Logic.java
- 
Logicuses theUltiStudentParserclass to parse the user command. - 
This results in a
Commandobject which is executed by theLogicManager. - 
The command execution can affect the
Model(e.g. adding a homework). - 
The result of the command execution is encapsulated as a
CommandResultobject which is passed back to theUi. - 
In addition, the
CommandResultobject can also instruct theUito perform certain actions, such as displaying help to the user. 
Given below is the Sequence Diagram for interactions within the Logic component for the execute("delete 1") API call.
delete 1 Command3.4. Model component
API : Model.java
The Model,
- 
stores a
UserPrefobject that represents the user’s preferences. - 
stores the UltiStudent data.
 - 
exposes an unmodifiable
ObservableList<Homework>that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. - 
does not depend on any of the other three components.
 
3.5. Storage component
API : Storage.java
The Storage component,
- 
can save
UserPrefobjects in json format and read it back. - 
can save the UltiStudent data in json format and read it back.
 
3.6. Common classes
Classes used by multiple components are in the seedu.ultistudent.commons package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1. Adding a homework: add-hw
The add homework feature is a core feature to the Homework Manager of UltiStudent. Which allows the users to create a homework object in UltiStudent.  | 
4.1.1. Overview
The add homework add-hw mechanism is facilitated by AddHomeworkCommand and AddHomeworkCommandParser.
It takes in the following input from the user: ModuleCode, HomeworkName and Date, which will
construct individual objects that construct a Homework object.
The AddHomeworkCommandParser implements Parser with the following operation:
- 
AddHomeworkCommandParser#parse()- This operation will take in aStringinput from the user that will create individual objects based on the prefixes 'mc/', 'hw/' and 'd/'. TheStringvalue after the individual prefixes will create the respective object: 'mc/' forModuleCode, 'hw/' forHomeworkNameand 'd/' forDate. A validation check will be imposed upon the creation of each object. Any checks that fails the validation would prompt the user on the failed component. For example:- 
ModuleCodewould useParserUtil#parseHomeworkModuleCode()to ensure that user has input 2 letters followed by 4 digits with an option to include a optional letter after the 4 digits. - 
HomeworkNamewould useParserUtil#parseHomeworkName()to ensure that homework name is not a null. - 
Datewould useParserUtil#parseDate()to ensure that user has entered a date that is either a present or future date. 
 - 
 - 
After validation checks are completed with no errors, a
Homeworkobject is then constructed withModuleCode,HomeworkNameandDateas the parameters - 
AddHomeworkCommandParserwould then return aAddHomeworkCommandobject with theHomeworkas the parameter 
Take a look at the code snippet of AddHomeworkCommandParser below for an illustration:
4.1.2. Example
Given below is an example usage scenario of how add-hw mechanism behaves at each step.
Step 1: The user executes add-hw mc/CS1101S hw/Tutorial 1 d/01/05/2019 to add a CS1101S Tutorial 1
homework with the deadline on 1st May 2019.
Step 2: LogicManager would use UltiStudentParser#parse() to parse the input from the user.
Step 3: UltiStudentParser would determine which command is being used and creates the respective
parser. In this case, AddHomeworkCommandParser is being created and the user’s input would be pass in
as a parameter.
Step 4: AddHomeworkCommandParser would do a validation check on the user’s input before creating
and returning a AddHomeworkCommand object with Homework as the parameter.
Step 5: LogicManager would use AddHomeWorkCommand#execute() to add the
ModuleCode and Homework
into the Model which is handled by ModelManager
Step 6: AddHomeworkCommand would return a CommandResult to the LogicManager which would then
be return back to the user.
The image below illustrates the scenario of when the user executes add-hw mc/CS1101S hw/Tutorial 1
d/01/05/2019:
add-hw4.2. Delete homework feature
This feature allows the user to delete a homework entry from the homework manager through its index.
The delete homework feature is facilitated by the DeleteHomeworkCommandParser and the DeleteHomeworkCommand.
The delete command is part of the logic component of our application. It interacts with the model and the storage components of our application.
4.2.1. Overview
The DeleteHomeworkCommandParser implements Parser with the following operation:
- 
DeleteHomeworkCommandParser#parse()- This operation will take in aintinput from the user which will delete the homework entry at the index which has entered. Any invalid format of the command will be prompted by the command parser. 
4.2.2. Current Implementation
The delete homework feature is executed by the DeleteHomeworkCommand. Currently, the
deletion of any homework entry is done based on the INDEX of the homework entry.
During the design of our delete function, we considered between two alternatives.
| Design Consideration | Pros and Cons | 
|---|---|
Deletion by Index (Current Choice)  | 
Pros: Since each homework has a unique index, any deletion by the index is less prone to bugs and easier to implement. Cons: User will have to scroll for the homework entry and look for its index which can be inconvenient  | 
Deletion by Homework Name  | 
Pros: It may be more intuitive for users to delete a homework through the name of the homework. Cons: Homework for different modules can have different names. For example, two different homework entries for two different modules can be called 'Tutorial 1'.  | 
We have decided to opt for the first option primarily because it reduces the number of potential bugs and the complexities involved when taking into account the different cases upon using deletion by homework name.
4.3. Edit homework feature
This feature allows the user to edit any attribute of the homework entries. This is a core feature because the user may have to update deadline or make corrections to mistakes, such as typographical errors, when adding a homework entry. There are a total of three attributes for each entry, the module code, the homework name and the deadline. The user can edit at least one and up to three attributes.
The edit homework feature is facilitated by the EditHomeworkCommandParser and the EditHomeworkCommand.
The edit command is part of the logic component of our application. It interacts with the model component of our software architecture.
4.3.1. Overview
The EditHomeworkCommandParser implements Parser with the following operation:
- 
EditHomeworkCommandParser#parse()- This operation will take in anintinput and one to threeStringinput(s) from the user that will alter the attributes of current homework entries based on the prefixes 'mc/', 'hw/' and 'd/'. TheStringvalue after the individual prefixes will alter the respective attribute it corresponds to: 'mc/' forModuleCode,'hw/' forHomeworkNameand 'd/' forDate. A validation check will be imposed upon editing of each object. Any checks that fails the validation would prompt the user on the failed component. 
4.3.2. Current Implementation
Here is an example of a step-by-step process on how the edit command alters an attribute of the homework entry.
For each step, you may follow the activity diagram at the end of this section to better understand the flow of events
within UltiStudent when an edit-hw command is inputted.
Step 1. The user launches the application and opens the homework manager. There is a list of existing homework entries in the homework manager.
Step 2. The user then wishes to alter the homework deadline of the third entry in the homework list to 10 May 2019.
He then types edit-hw d/10/05/2019 into the Command Line Interface (CLI) and executes it.
Step 3. The UltiStudentParser (refer to logic) then reads in these attributes that have been inputted and proceeds to alter the attributes of the homework entry in the given index. Each attribute will be validated.
Step 4. The UltiStudentParser then creates a new EditHomeworkCommand based on the input of the user. When the EditHomeworkCommand is executed, it interacts with the Model architecture by calling the setHomework method. The setHomework method replaces the current homework entry with the a new homework entry containing all the desired attributes. The homework entry is now updated.
Step 5. If the module code for any homework entry has been edited to a module code that is not in the module code list, the EditHomeworkCommand will add the new module code into the module code list. The updated module code list will be displayed on our User Interface.
edit-hwIn designing the edit homework feature, we considered if we should use an alternative data structure to update the list of module codes. We considered using a hash map to map the module code to the number of homework with the modules to check if the module code list has to be updated for each edit.
| Design Consideration | Pros and Cons | 
|---|---|
Update ModuleList by iteration (Current Choice)  | 
Pros: Protects the abstraction layers and modularity by restricting the usage to the existing data structures already present in our code. Cons: Less efficient in terms of time and actual time taken can be long when number of entries is large.  | 
Update ModuleList using help from other data structures.  | 
Pros: Faster expected performance. Cons: Introducing a new data structure can disrupt the existing abstractions of our code.  | 
To sum up our justification of our choice of design, we decided to opt for the first option because we prioritised the existing design abstractions in our code over the efficiency of our code.
4.4. Find module feature
This feature allows the user to only display homework belonging to one or more module codes which is user has specified. The find module feature is exceptionally useful to shorten the displayed list of homework.
The find module feature is facilitated by the FindModuleCommandParser and the FindModuleCommand.
It interacts with the model component of our architecture to retrieve the list homework.
4.4.1. Overview
The FindModuleCommandParser implements Parser with the following operation:
- 
FindModuleCommandParser#parse()- This operation will take in at least oneStringinput from the user and display any of the homework entries with matches any of list of[KEYWORDS]that the user has inputted. Each keyword is separated by a white space. Any homework entry that matches with the list of keywords will be displayed on the homework list. 
4.4.2. Current Implementation
The find module feature is facilitated by the FindModuleCommand.
Here is a sequence of steps on how the find module feature works. We will use an example here to help you understand the flow of events. In the steps below, we will make references to the diagram at the end of the section to help you visualise the sequence of events better.
Step 1. The user first launches the application and enters the homework manager. There are already existing homework entries within the homework list.
Step 2. Currently, there are a total of twelve homework entries belonging to four modules.
(Do note that this is an arbitrary state of the storage in the homework manager and is meant to serve as an example.)
Now the user inputs find mod CS1101S. Referring to the diagram below, UltiStudentCommandParser
parses the command find-mod together with the list of keywords.
Step 3. The FindModuleParser then creates a FindModuleCommand and then returns it to the LogicManager, which are illustrated by the blue arrows pointing from the command parsers back to the LogicManger.
Step 4. Now, the Logic Manager then executes this command. When the find command is executed, it called the method updateFilteredList, which then returns a list of homework that has the module codes which matches any of the key words inputted back to the Logic Manager as indicated by the purple arrows pointing back to the Logic Manager’s blue block.
find-mod4.5. Adding a note : add-note
The add homework feature is a core feature to the Homework Manager of UltiStudent. Which allows the users to create a homework object in UltiStudent.  | 
4.5.1. Overview
The add note add-note mechanism is facilitated by AddNoteCommand and
AddNoteCommandParser.
It takes in the following input from the user: ModuleCode and NoteName
which will construct individual objects that construct a Note object.
The AddNoteCommandParser implements Parser with the following operation:
- 
AddNoteCommandParser#parse()- This operation will take in aStringinput from the user that will create individual objects based on the prefixes 'mc/' and 'n/'. TheStringvalue after the individual prefixes will create the respective object: 'mc/' forModuleCodeand 'n/' forNoteName. A validation check will be imposed upon the creation of each object. Any checks that fails the validation would prompt the user on the failed component. 
For example:
- 
ModuleCodewould useParserUtil#parseNoteModuleCodeto ensure that user has input 2 letters followed by 4 digits with an option to include a optional letter after the 4 digits. - 
NoteNamewould useParserUtil#parseNoteNameto ensure that note name is not a null.- 
After validation checks are completed with no errors, a
Noteobject is then constructed withModuleCodeandNoteName. - 
AddNoteCommandParserwould then return aAddNoteCommandobject with theNoteas the parameter 
 - 
 
4.5.2. Example
Given below is an example usage scenario of how add-note mechanism behaves at
each step.
Step 1: The user executes `add-note mc/CS2103T n/Week 1 Lecture to add a note for CS2103T Week 1 Lecture.
Step 2: LogicManager would use UltiStudentParser#parse() to parse the input from the user.
Step 3: UltiStudentParser would determine which command is being used and creates the respective
parser. In this case, AddNoteCommandParser is being created and the user’s
input would be pass in as a parameter.
Step 4: AddNoteCommandParser would do a validation check on the user’s input
 before creating and returning a AddNoteCommand object with Note
 as the parameter.
Step 5: LogicManager would use AddNoteCommand#execute() to add the
ModuleCode and Note
into the Model which is handled by ModelManager
Step 6: AddNoteCommand would return a CommandResult to the LogicManager
which would then be return back to the user.
The image below illustrates the scenario of when the user executes add-hw mc/CS1101S hw/Tutorial 1
d/01/05/2019:
add-note4.6. Deleting a note : delete-note
This feature allows the user to delete a note from the homework manager through its index.
The delete note feature is facilitated by the DeleteNoteCommandParser and
the DeleteNoteCommand.
The delete command is part of the logic component of our application. It interacts with the model and the storage components of our application.
4.6.1. Overview
The DeleteNoteCommandParser implements Parser with the following operation:
- 
DeleteNoteCommandParser#parse()- This operation will take in aintinput from the user which will delete the note entry at the index which has entered. Any invalid format of the command will be prompted by the command parser. 
4.6.2. Current Implementation
The delete note feature is executed by the DeleteNoteCommand. Currently,
 the deletion of any note entry is done based on the INDEX of the
 note entry.
During the design of our delete function, we considered between two alternatives.
| Description of Implementation | Pros and Cons | 
|---|---|
Deletion by Index (Current Choice)  | 
Pros: Since each note has a unique index within each list, deleting a note by its index is less prone to bugs and will be easier to implement. Cons: User will need to scroll for the entry and look for its index which can be inconvenient.  | 
Deletion by Homework Name  | 
Pros: It may be more intuitive for users to delete a note through its note name. Cons: Notes for different modules can have similar names. For example, two different note entries for two different modules can be called 'Week 7 Lecture'. This may cause it to be more error-prone.  | 
We have decided to opt for the first option primarily because it reduces the number of potential bugs and the complexities involved when taking into account the different cases upon using deletion by note name.
4.7. Editing and Saving a note : edit-note save-note
These two feature allows the user to edit existing note and save them after editing.  | 
4.7.1. Overview
The edit-note command helps the user to open the selected notes to allow the user to start editing its content
by displaying all the content on the NotesManagerMainPanel which is a text field. It requires the need of the
save-note command to help save the user’s edits
Below is an activity diagram of how the users use edit-note and save-note to facilitate adding contents to
their existing notes:
edit-note and save-noteStep 1: User will key in edit-note INDEX on the command line
Step 2: System will do a validation check to see if INDEX of note exist in the list of notes in the Model.
If note does not exist, it will throw a ParserException to the user. Else note will be opened and proceed to
step 3.
Step 3: Once it is opened, NotesManagerMainPanel will be enabled, allowing the user to start typing their
notes in the text field.
Step 4: When the user is done editing, he/she can use save-note in the command line to save the edited
content to the opened note.
Step 5: Upon successful save, NotesManagerMainPanel will be disabled and user will not be able to type
anything on NotesManagerMainPanel
4.7.2. Design Considerations
Options  | 
Pro  | 
Cons  | 
1. Users to type their content on the command line  | 
- Easy implementation  | 
- Not user friendly  | 
2. Users to type their content on the   | 
- User friendly  | 
- Two sources of input, Command Line and TextField  | 
Option 2 is being selected and implemented as we focus on the users convenience and the ability to edit their notes easily. Separation of command line and notes text field would reduce the number of commands the user has to remember and there will be lesser confusion of command line mode or text input mode.
4.8. Editing a Cap Entry : edit-cap
This feature allows the user to edit a cap entry from the cap entry list. Users can do so either via:
the cap entry’s index with the edit-cap command or the cap entry’s module code with the edit-cap-mc
4.8.1. Current Implementation
The edit-cap command is facilitated by the Logic and Model components of the application, UltiStudent.
The sequence diagram below shows how the editing of cap entries work when the user enters
edit-cap
edit-capThe sequence diagram for the "Update Module Semester" reference frame above can be seen below.
Given below is an example usage scenario of how edit-cap behaves at each step.
Step 1: The user launches the application and opens the CAP Manager.
Step 2: There are already existing CAP entries. The user now executes edit-cap 2 g/A sem/Y2S2 to edit the cap entry in the 2nd index with grade A and
moduleSemester of Y2S2.
Step 3: Upon executing this command, the EditCapCommandParser will take in all the arguments inputted and create a
EditCapCommand object. This object is then returned to the Logic Manager which will then execute the EditCommand
Step 4: When executing the EditCapCommand this alters the attributes of the CAP Entry in the UniqueCapEntryList object of
UltiStudent by setCapEntry(a,b) method, where a is the cap entry to edit, and b is the edited cap entry.
In doing so, this will call the method of updateCapForDelete(a) and updateCapForAdd(b), which will update the CAP score.
Step 5: Next, the UniqueModuleSemesterList will be updated. This is done by the updateModuleSemesterList(x,y) where x is
the moduleSemesterOfCapEntry to edit, while y is the moduleSemesterOfEditedCapEntry.
Step 6: If moduleSemesterOfCapEntry is different from moduleSemesterOfEditedCapEntry, the model will check if it
contains moduleSemesterOfEditedCapEntry. If it does not, moduleSemesterOfEditedCapEntry will be added to
the UniqueModuleSemesterList.
Step 7: On the other hand, if the model does not have any cap entries with the same semesters as
moduleSemesterOfCapEntry after editing the cap entries, which is reflected if hasCapEntriesWithSameSemester is false.
The moduleSemesterOfCapEntryToEdit will be deleted to the UniqueModuleSemesterList.
4.8.2. Design Considerations
Aspect: How to store the Cap Score.
- 
Alternative 1 (current choice): Store the cap score as a static variable in CapEntry class.
- 
Pros: Easy to implement.
 - 
Cons: Since a static variable belongs to the CapEntry class, there may be unintended side effects when we use commands to modify the
UniqueCapEntryList. 
 - 
 - 
Alternative 2: Store the cap score as a separate class that is then store in UltiStudent.
- 
Pros: Each versioned UltiStudent will have their own cap score.
 - 
Cons: Will use more memory and is harder to implement.
 
 - 
 
Aspect: How to assign score for module grade.
- 
Alternative 1 (current choice): Use a Hash Map to get the Store the cap score as a static variable in CapEntry class.
- 
Pros: Lower time complexity O(1) and cleaner code.
 - 
Cons: Larger memory occupation.
 
 - 
 - 
Alternative 2: Use switch cases to find and allocate score to grade.
- 
Pros: Easier readability.
 - 
Cons: Slower time complexity, worst case of O(N).
 
 - 
 
4.9. Deleting a Cap Entry : delete-cap
This feature allows the user to delete a cap entry from the cap entry list. Users can do so either via:
the cap entry’s index with the delete-cap command or the cap entry’s module code with the delete-cap INDEX
4.9.1. Current Implementation
The delete-cap command is facilitated by the Logic and Model components of the application, UltiStudent.
The activity diagram below shows how the deleting of cap entries work when the user enters
delete-cap.
delete-capGiven below is an example usage scenario of how delete-cap behaves at each step.
Step 1: The user executes delete-cap 2 to delete the cap entry in the 2nd index.
Step 2: Upon executing this command, the DeleteCapCommandParser parses the arguments and checks if the arguments are valid.
If not valid, the command throws an exception and terminates.
Step 3: If the argument is valid, the command checks if the CapEntry exists in the CAP Manager. If it does, the entry is deleted.
The UniqueCapEntryList is then updated and the CAP score is updated as well.
Step 4: Check if after deleting the target CapEntry the UniqueCapEntryList still has a CapEntry of the same semester. If there is,
the module semester will be deleted from the UniqueModuleSemesterList. Then the UniqueModuleSemesterList will be updated.
4.10. Logging
We are using java.util.logging package for logging. The LogsCenter class is used to manage the logging levels and logging destinations.
- 
The logging level can be controlled using the
logLevelsetting in the configuration file (See Section 4.11, “Configuration”) - 
The
Loggerfor a class can be obtained usingLogsCenter.getLogger(Class)which will log messages according to the specified logging level - 
Currently log messages are output through:
Consoleand to a.logfile. 
Logging Levels
- 
SEVERE: Critical problem detected which may possibly cause the termination of the application - 
WARNING: Can continue, but with caution - 
INFO: Information showing the noteworthy actions by the App - 
FINE: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size 
4.11. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json).
5. Documentation
We use asciidoc for writing documentation.
| We chose asciidoc over Markdown because asciidoc, although a bit more complex than Markdown, provides more flexibility in formatting. | 
5.1. Editing Documentation
See UsingGradle.adoc to learn how to render .adoc files locally to preview the end result of your edits.
Alternatively, you can download the AsciiDoc plugin for IntelliJ, which allows you to preview the changes you have made to your .adoc files in real-time.
5.2. Publishing Documentation
See UsingTravis.adoc to learn how to deploy GitHub Pages using Travis.
5.3. Converting Documentation to PDF format
We use Google Chrome for converting documentation to PDF format, as Chrome’s PDF engine preserves hyperlinks used in webpages.
Here are the steps to convert the project documentation files to PDF format.
- 
Follow the instructions in UsingGradle.adoc to convert the AsciiDoc files in the
docs/directory to HTML format. - 
Go to your generated HTML files in the
build/docsfolder, right click on them and selectOpen with→Google Chrome. - 
Within Chrome, click on the
Printoption in Chrome’s menu. - 
Set the destination to
Save as PDF, then clickSaveto save a copy of the file in PDF format. For best results, use the settings indicated in the screenshot below. 
5.4. Site-wide Documentation Settings
The build.gradle file specifies some project-specific asciidoc attributes which affects how all documentation files within this project are rendered.
Attributes left unset in the build.gradle file will use their default value, if any.
 | 
| Attribute name | Description | Default value | 
|---|---|---|
  | 
The name of the website. If set, the name will be displayed near the top of the page.  | 
not set  | 
  | 
URL to the site’s repository on GitHub. Setting this will add a "View on GitHub" link in the navigation bar.  | 
not set  | 
  | 
Define this attribute if the project is an official SE-EDU project. This will render the SE-EDU navigation bar at the top of the page, and add some SE-EDU-specific navigation items.  | 
not set  | 
5.5. Per-file Documentation Settings
Each .adoc file may also specify some file-specific asciidoc attributes which affects how the file is rendered.
Asciidoctor’s built-in attributes may be specified and used as well.
Attributes left unset in .adoc files will use their default value, if any.
 | 
| Attribute name | Description | Default value | 
|---|---|---|
  | 
Site section that the document belongs to.
This will cause the associated item in the navigation bar to be highlighted.
One of:  * Official SE-EDU projects only  | 
not set  | 
  | 
Set this attribute to remove the site navigation bar.  | 
not set  | 
5.6. Site Template
The files in docs/stylesheets are the CSS stylesheets of the site.
You can modify them to change some properties of the site’s design.
The files in docs/templates controls the rendering of .adoc files into HTML5.
These template files are written in a mixture of Ruby and Slim.
| 
 Modifying the template files in   | 
6. Testing
6.1. Running Tests
There are three ways to run tests.
| The most reliable way to run tests is the 3rd one. The first two methods might fail some GUI tests due to platform/resolution-specific idiosyncrasies. | 
Method 1: Using IntelliJ JUnit test runner
- 
To run all tests, right-click on the
src/test/javafolder and chooseRun 'All Tests' - 
To run a subset of tests, you can right-click on a test package, test class, or a test and choose
Run 'ABC' 
Method 2: Using Gradle
- 
Open a console and run the command
gradlew clean allTests(Mac/Linux:./gradlew clean allTests) 
| See UsingGradle.adoc for more info on how to run tests using Gradle. | 
Method 3: Using Gradle (headless)
Thanks to the TestFX library we use, our GUI tests can be run in the headless mode. In the headless mode, GUI tests do not show up on the screen. That means the developer can do other things on the Computer while the tests are running.
To run tests in headless mode, open a console and run the command gradlew clean headless allTests (Mac/Linux: ./gradlew clean headless allTests)
6.2. Types of tests
We have two types of tests:
- 
GUI Tests - These are tests involving the GUI. They include,
- 
System Tests that test the entire App by simulating user actions on the GUI. These are in the
systemtestspackage. - 
Unit tests that test the individual components. These are in
seedu.ultistudent.uipackage. 
 - 
 - 
Non-GUI Tests - These are tests not involving the GUI. They include,
- 
Unit tests targeting the lowest level methods/classes.
e.g.seedu.ultistudent.commons.StringUtilTest - 
Integration tests that are checking the integration of multiple code units (those code units are assumed to be working).
e.g.seedu.ultistudent.storage.StorageManagerTest - 
Hybrids of unit and integration tests. These test are checking multiple code units as well as how the are connected together.
e.g.seedu.ultistudent.logic.LogicManagerTest 
 - 
 
6.3. Troubleshooting Testing
Problem: HelpWindowTest fails with a NullPointerException.
- 
Reason: One of its dependencies,
HelpWindow.htmlinsrc/main/resources/docsis missing. - 
Solution: Execute Gradle task
processResources. 
7. Dev Ops
7.1. Build Automation
See UsingGradle.adoc to learn how to use Gradle for build automation.
7.2. Continuous Integration
We use Travis CI and AppVeyor to perform Continuous Integration on our projects. See UsingTravis.adoc and UsingAppVeyor.adoc for more details.
7.3. Coverage Reporting
We use Coveralls to track the code coverage of our projects. See UsingCoveralls.adoc for more details.
7.4. Documentation Previews
When a pull request has changes to asciidoc files, you can use Netlify to see a preview of how the HTML version of those asciidoc files will look like when the pull request is merged. See UsingNetlify.adoc for more details.
7.5. Making a Release
Here are the steps to create a new release.
- 
Update the version number in
MainApp.java. - 
Generate a JAR file using Gradle.
 - 
Tag the repo with the version number. e.g.
v0.1 - 
Create a new release using GitHub and upload the JAR file you created.
 
7.6. Managing Dependencies
A project often depends on third-party libraries. For example, UltiStudent depends on the Jackson library for JSON parsing. Managing these dependencies can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives:
- 
Include those libraries in the repo (this bloats the repo size)
 - 
Require developers to download those libraries manually (this creates extra work for developers)
 
Appendix A: Product Scope
Target user profile:
- 
university student
 - 
prefer desktop apps over other types
 - 
can type fast
 - 
prefers typing over mouse input
 - 
is reasonably comfortable using CLI apps
 
Value proposition: manage student life faster and better than a typical mouse/GUI driven app
Appendix B: User Stories
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… | 
|---|---|---|---|
  | 
new user  | 
see usage instructions  | 
refer to instructions when I forget how to use the App  | 
  | 
user  | 
add a new person  | 
|
  | 
user  | 
delete a person  | 
remove entries that I no longer need  | 
  | 
user  | 
find a person by name  | 
locate details of persons without having to go through the entire list  | 
  | 
user  | 
hide private contact details by default  | 
minimize chance of someone else seeing them by accident  | 
  | 
user with many persons in the UltiStudent  | 
sort persons by name  | 
locate a person easily  | 
{More to be added}
Appendix C: Use Cases
(For all use cases below, the System is the AddressBook and the Actor is the user, unless specified otherwise)
Use case: Delete person
MSS
- 
User requests to list persons
 - 
AddressBook shows a list of persons
 - 
User requests to delete a specific person in the list
 - 
AddressBook deletes the person
Use case ends.
 
Extensions
- 
2a. The list is empty.
Use case ends.
 - 
3a. The given index is invalid.
- 
3a1. AddressBook shows an error message.
Use case resumes at step 2.
 
 - 
 
{More to be added}
Appendix D: Non Functional Requirements
- 
Should work on any mainstream OS as long as it has Java
9or higher installed. - 
Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage.
 - 
A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
 
{More to be added}
Appendix F: Product Survey
Product Name
Author: …
Pros:
- 
…
 - 
…
 
Cons:
- 
…
 - 
…
 
Appendix G: Instructions for Manual Testing
Given below are instructions to test the app manually.
| These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. | 
G.1. Launch and Shutdown
- 
Initial launch
- 
Download the jar file and copy into an empty folder
 - 
Double-click the jar file
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum. 
 - 
 - 
Saving window preferences
- 
Resize the window to an optimum size. Move the window to a different location. Close the window.
 - 
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained. 
 - 
 
G.2. Opening a manager
- 
Opening respective manager with the command:
open- 
Prerequisites: Currently in Homework Manager with Homework icon being highlighted.
 - 
Test case:
open HomeworkManager
Expected: UI does not change changes - 
Prerequisites: Currently in other Manager with Homework icon not being highlighted.
 - 
Test case:
open HomeworkManager
Expected: HomeworkManager is opened and GUI of HomeworkManager is shown - 
Prerequisites: Currently in Notes Manager with Notes icon being highlighted.
 - 
Test case:
open NotesManager
Expected: UI does not change changes - 
Prerequisites: Currently in other Manager with Homework icon not being highlighted.
 - 
Test case:
open NotesManager
Expected: NotesManager is opened and GUI of NotesManager is shown - 
Prerequisites: Currently in Cap Manager with Notes icon being highlighted.
 - 
Test case:
open CapManager
Expected: UI does not change changes - 
Prerequisites: Currently in other Manager with Homework icon not being highlighted.
 - 
Test case:
open CapManager
Expected: CapManager is opened and GUI of CapManager is shown 
 - 
 
G.3. Adding a homework
Adding a homework with the command: add-hw
- 
Prerequisites: HomeworkManager has to be opened to see changes on GUI. (i.e. "open HomeworkManager" command has to be ran first)
 - 
Test case:
add-hw mc/CS2103T hw/Tutorial 1 d/22/05/2019
Expected: A homework will be added into the list of homework in the Homework Main Panel. The module code in which homework belongs to is also added in the Homework SubPanel list if not present before. - 
Test case:
add-hw mc/CSXXXXT hw/Tutorial 1 d/22/05/2019
Expected: No homework is added. Error details will be shown in the status message. - 
Other incorrect add-hw commands to try :
add-hw,add-hw mc/CS2103T hw/Tutorial 1 d/dd/MM/YYYY(where dd/MM/YYYY is a past date)
Expected: Similar to previous. 
G.4. Deleting a homework entry
- 
Deleting a homework while all homework are listed with the command:
delete-hw- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil autonmatically generates sample data when the json file is empty.
 - 
Test case:
delete-hw 1
Expected: First homework is deleted from the list. Details of the deleted homework shown in the status message. Timestamp in the status bar is updated. - 
Test case:
delete-hw 0
Expected: No homework is deleted. Error details shown in the status message. Status bar remains the same. - 
Other incorrect delete commands to try:
delete-hw,delete-hw x(where x is larger than the list size)
Expected: Similar to previous. 
 - 
 
G.5. Editing a homework entry
Edit a homework while all homework are listed with the command: edit-hw
- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample data when the json file is empty.
 - 
Test case:
edit-hw 1 d/30/05/2019
Expected: The deadline of the first homework is changed to 30/05/2019. Details of the edited homework shown in the status message. Timestamp in the status bar is updated. - 
Test case:
edit-hw 0
Expected: No homework is edited. Error details shown in the status message. Status bar remains the same. - 
Other incorrect edit commands to try:
edit-hw,edit-hw x(where x is larger than the list size),edit-hw 30/05/2019
Expected: Similar to previous. 
G.6. Finding homework entries of which contains this module
Finds homework that has a homework module and displays these modules in a list with the command: find-mod
- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample data when the json file is empty.
 - 
Test case:
find-mod CS2030
Expected: The homework list displays homeworks that has CS2030 as part of its homework module. - 
Test case:
find-mod xwhere x is any module code that is not present in the module code list.
Expected: No homework is displayed in the homework list. Status bar shows that "0 homework listed!" 
G.7. List all homework entries
Lists all existing homework entries with the command: list-hw
- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample data when the json file is empty.
 - 
Test case:
find-mod CS2030followed bylist-hw
Expected: The homework list displays all existing homework entry. 
G.8. Adding a note
Adding a note with the command: add-note
- 
Prerequisites: NotesManager has to be opened. (i.e. "open NotesManager" command has to be ran first)
 - 
Test case:
add-note mc/CS2103T n/Week 7 TutorialExpected: A note will be added into the list of note in the Notes Main Panel. - 
Test case:
add-note mc/CSXXXXT n/Tutorial 1Expected: No note is added. Error details will be shown in the status message. - 
Other incorrect add-note commands to try :
add-note,add-note mc/CS2103T n/(where note name is a whitespace) Expected: Similar to previous. 
G.9. Deleting a note
- 
Deleting a note while all note are listed with the command:
delete-note- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil autonmatically generates sample data when the json file is empty.
 - 
Test case:
delete-note 1
Expected: First note is deleted from the list. Details of the deleted note shown in the status message. Timestamp in the status bar is updated. - 
Test case:
delete-note 0
Expected: No note is deleted. Error details shown in the status message. Status bar remains the same. - 
Other incorrect delete commands to try:
delete-note,delete-note x(where x is larger than the list size)
Expected: Similar to previous. 
 - 
 
G.10. Editing a Note
Editing a note with the command : edit-note
- 
Prerequisites: NotesManager has to be opened (i.e.
open NotesManagercommand has to be ran first). Multiple notes in the notes list. - 
Test case:
edit-note 1
Expected: First note will be selected and the contents of the selected note will be populated in the text area in the NotesMainPanel. - 
Test case:
edit-note 0
Expected: No note will be selected. Error details will be shown in the status message. - 
Other incorrect edit note commands to try:
edit-note
Expected: Similar to previous. 
G.11. Saving a Note
Saving a note with the command : save-note
- 
Prerequisites: NotesManager has to be opened (i.e.
open NotesManagercommand has to be ran first). Multiple notes in the notes list. A note has to be selected (i.eedit-note INDEXcommand has to ran to select a note atINDEX) - 
Test case:
save-note
Expected: Contents of selected note will be saved. Details of note will be shown in the status message. - 
Prerequisites: NotesManager has to be opened and no note is being selected.
 - 
Test case:
save-note
Expected: Error details will be shown in the status message. 
G.12. Adding a cap entry
Adding a cap entry while all cap entries are listed with the command: add-cap
- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample Data when the UltiStudent.json file is corrupted or unavailable.
 - 
Test case:
add-cap mc/CS3203 g/B mcs/8 sem/Y1S1
Expected: Cap entry with module code CS1010, grade of B, 4MCs, Y1S1 is added. Details of the first cap entry shown in the status message. Timestamp in the status bar is updated. CAP score displayed is updated. - 
Test case:
add-cap mc/CS3203 g/B mcs/100 sem/Y1S1Expected: No cap entry is added. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Test case:
add-cap mc/CS55555 g/B mcs/100 sem/Y1S1Expected: No cap entry is added. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Test case:
add-cap mc/CS55555 g/B mcs/100 sem/Y1S3Expected: No cap entry is added. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Other incorrect edit commands to try:
add-cap mc/1234 g/A+ mcs/4 sem/Y2S2{give more}
Expected: Similar to previous. 
G.13. Deleting a cap entry
Deleting a cap entry while all cap entries are listed with the command: delete-cap
- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample Data when the UltiStudent.json file is corrupted or unavailable.
 - 
Test case:
delete-cap 1
Expected: First cap entry is deleted. Details of the deleted cap entry shown in the status message. Timestamp in the status bar is updated. CAP score displayed is updated. - 
Test case:
delete-cap 0
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Test case:
delete-cap xwhere x is larger than the list size
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Test case:
delete-cap xwhere x is negative number
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Other incorrect delete commands to try:
delete,delete x(where x is larger than the list size) {give more}
Expected: Similar to previous. 
G.14. Editing a cap entry
Editing a cap entry while all cap entries are listed with the command: edit-cap
- 
Prerequisites: Use the sample data that using SampleDataUtil. SampleDataUtil automatically generates sample Data when the UltiStudent.json file is corrupted or unavailable.
 - 
Test case:
edit-cap 1 g/A mcs/4
Expected: First cap entry is edited. Details of the first cap entry shown in the status message. Timestamp in the status bar is updated. CAP score displayed is updated. - 
Test case:
edit-cap 0 g/A mcs/4
Expected: No cap entry is edit. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Test case:
edit-cap x g/B mcs/4where x is larger than the list size
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Test case:
edit-cap x g/B mcs/4where x is negative number
Expected: No cap entry is deleted. Error details shown in the status message. Status bar remains the same. Current CAP score stays the same. - 
Other incorrect edit commands to try:
edit,edit x(where x is larger than the list size) {give more}
Expected: Similar to previous.