Developer Guide
-
StudyBananas - Developer Guide
- 1. Introduction
- 2. Setting up and getting started
- 3. Design
- 4. Implementation
- 5. Documentation, logging, testing, configuration, dev-ops
-
6. Appendix: Requirements
- 6.1. Product scope
- 6.2. User stories
-
6.3. Use cases
- Use case: UC01 Create a set of flashcards
- Use case: UC02 Create and add an individual flashcard into a set
- Use case: UC03 See all existing flashcard sets
- Use case: UC04 Delete a flashcard set
- Use case: UC05 See all flashcards in a flashcard set
- Use case: UC06 Delete an individual flashcard from a set
- Use case: UC07 Quiz of flashcard set (no storage of answer)
- Use case: UC08 Quiz of flashcard set (with storage of answer)
- Use case: UC09 Add a task to the schedule
- Use case: UC10 Delete a task
- Use case: UC11 Search for tasks
- Use case: UC12 View all tasks
- Use case: UC13 View quiz score and past attempt
- 6.4. Non-Functional Requirements
- 6.5. Glossary
- 6.6. Product survey
- 7. Appendix: Instructions for manual testing
StudyBananas - Developer Guide
By: AY2021S1-CS2103T-F12-2
1. Introduction
This document is a Developer Guide written for developers who wish to contribute to or extend our project. It is technical, and explains the inner workings of StudyBananas and how the different components of our application work together.
Reading this Developer Guide
| Icon | Remarks |
|---|---|
| 💡 | This icon denotes useful tips to note of during development. |
| ❗️ | This icon denotes important details to take note of during development. |
The diagrams in this Developer Guide are colour coded according to the different components.

2. Setting up and getting started
Refer to the guide Setting up and getting started.
3. Design
3.1. Architecture
StudyBananas is a brown field project adapted and developed upon AddressBook3. Our team decides to reuse the overall architecture by maintaining the system with 6 components (listed in the picture above) but scale each component to cater the need of StudyBananas. The Architecture Diagram given above explains the high-level design of the StudyBananas, which is inherited from AddressBook3. Given below is an overview of each component, we will explain how each component works internally, and how do we scale the system, which can server as a guideline for the developers to expand StudyBananas.
.puml files used to create diagrams in this document can be found in the diagrams folder. Refer to the PlantUML Tutorial at se-edu/guides to learn how to create and edit diagrams.
Main has two classes called Main and 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 methods where necessary.
Commons represents a collection of classes used by multiple other components.
The rest of the App consists of four components.
-
UI: The UI of the App. -
Logic: The command executor. -
Model: Holds the data of the App in memory. -
Storage: Reads data from, and writes data to, the hard disk.
Each of the four components,
- defines its API in an
interfacewith the same name as the Component. - exposes its functionality using a concrete
{Component Name}Managerclass (which implements the corresponding APIinterfacementioned in the previous point.
For example, the Logic component (see the class diagram given below) defines its API in the Logic.java interface and exposes its functionality using the LogicManager.java class which implements the Logic interface.
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 task 1.

The sections below give more details of each component.
3.2. Model Component
API : Model.java
The Model,
- stores the schedule, flashcard, and quiz history data.
- depends on three
ModelManagers - does not depend on any of the other three components.
The following paragraphs explain the structure of Model component.
3.2.1. Overall Structure
StudyBananas is an integration of 3 systems, namely Schedule, Quiz, and Flashcard. As mentioned in Architecture, we only have one API class (Model) for models from all three systems, this decision incurs strong couplings between three systems, resulting in many regression in the unit tests during the development. Therefore, to solve this problem, we introduce one more layer of abstraction for Model components to reduce the couplings. This section describes our implementation and analysis.
3.2.2. Implementation
The following is the step by step guide of how we structure Model component. We believe this structure reduces the coupling for models from different systems and preserves the benefit of one component, one API.
Step 1. Create XYZModel interfaces for each system. They work similar as APIs for individual systems, but other components in StudyBananas would not access them directly. Instead, we have our API Model interface extends from all of them to make sure there is still the only one API class for Model component.
Step 2. Create XYZModelManagers which implement the XYZModel and contain CRUD methods on the persistence data in StudyBananas.

Step 3. Create system-level Models (Schedule, Flashcard, Quiz) which are models that perform CRUD on the data. Then, create a dependency between XYZModelManagers and system-level Models so that the CRUD methods in XYZModelManager can take advantage of them.
Step 4. Finally, create our “one and only one” Model component API class - ModelManager which implements the Model interface and contains all the ModelManagers. In this way, although the ModelManager contains all the CRUD methods from 4 individual Models. It can be viewed as a dummy class which does not contain any implementation. All implementations are in the individual ModelManagers. Therefore, we are able to test the real implementation of one Model without the interference from other Models.
3.2.3. Analysis
- Pros:
- It preserves the advantage of easy and fast cooperation for people working on different components because there is only one API class required to work together.
- It solves the problem that testers have to implement unrelated methods for
ModelStuband avoids regression on unit tests of otherModelwhen oneModelis modified. Therefore,Modelno longer breaks Interface Segregation Principle. - Although adding new systems still requires adding methods in the Model interface, it makes sure that there is no need to modify other
Modeland newModelcan be included easily by havingModel APIextend it. Therefore, it meets the Open-Closed Principle.
- Cons:
- It still breaks the Single Responsibility Principle, for
Modelis no longer responsible for one model at a time, it holds accountable for models from 3 systems at the same time.
- It still breaks the Single Responsibility Principle, for
3.2.4. Structure for individual Model
ScheduleModel
FlashcardModel
QuizModel
3.3. UI component
API :
Ui.java
The UI consists of a MainWindow that is made up of parts e.g.CommandBox, ResultDisplay, PTaskListPanel 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.
The following paragraphs explain the structure of UI component in detail.
3.3.1. Overall Structure
StudyBananas contains three pages for three different systems. A user can navigate between different systems by entering commands or clicking on the tabs. Compared with AddressBook3, StudyBananas has a much higher complexity for UI component for the reason that StudyBananas supports navigation through clicking, which would require a state management structure to realize.
Our team divides UI state into two categories and manage their changes in two different ways, the following table provides the definition of these two types of state.
| Terminology | Definition | |
|---|---|---|
| Static State | The objects that would be used in many UI components, but either there wouldn’t be any changes made to them or they might be changed, but no components listen to their changes. |
|
| Dynamic State | The objects related to any reactive UI behavior. In other words, multiple components listen to the changes of them and we would expect view updates from the components when the state is changed. |
For the reason that these two states have intrinsic difference in their complexity (dynamic state is much more
complicated than the static state), we handle them differently in UI component. The following paragraphs explain our implementation on them separately.
3.3.2. Static State
3.3.2.1. Reasoning
When our team starts to improve the user experience of the graphical user interface, the first pain that came to our notice is that many components have the need for certain objects(static state), but due to the fact that Ui Components tend to nest each other, the developer might need to pass the object(static state) down to a deep nested component.
For example, many components take advantage of Logic object to communicate with the persistence data in Model component to provide accurate view of data.
The picture below is the simplified class diagram for Ui Components, and the Components with pink color depend on the Logic object. The red path is the deepest path that Logic object would need to be passed. You can observe the deep nested dependency in the graph.

3.3.2.2. Implementation (Solution)
The most intuitive solution is to make those static states globally accessible to every Component. By doing this, the static state does not need to be passed. Instead, only the components that require the static state need to depend on it. The following paragraph shows the step-by-step guide of the implementation.
Step 1. Create a class named GlobalState and make it singleton, and set the static states as the attributes of GlobalState. Then, use the set method to set the attribute of the GlobalState in the component where the static state is first created so that we are certain that when other components try to get the static state from the GlobalState, the static state has already been registered in the GlobalState.
GlobalState has to be singleton.
Step 2. Have the components that require the static state depend on the GlobalState to fetch and update the static state easily.
static state around anyone, the structure is thereby flatten.
3.3.2.3. Analysis
- Pros:
- This structure makes it easier for the developer to maintain the
Ui componentsbecause there is no need to passstatic stateas arguments for the constructor anymore - It avoids dummy arguments in some constructors. For example, given the following component structure A -> B -> C, if A and C both require a common
static state, in the original implementation, the constructor in B would need to have one more argument for thestatic statewhich is not used inComponent Bexcept for constructingComponent C. In this sense, thestatic stateis dummy inside the constructor B.
- This structure makes it easier for the developer to maintain the
- Cons:
- Every component is able to get access and modify the
static state, the modification done to astatic statein one class by a developer can cause unexpected behavior when another developer is using the samestatic statein other components.
- Every component is able to get access and modify the
GlobalState is inspired by
Redux. It has a much more complicated structure than what we have here.
3.3.3. Dynamic State
3.3.3.1. Reasoning
In the UI design phase, our team decided to build a sidebar and expected it to allow user to navigate through different pages by clicking. It was the first time that we found out that there are multiple components listening to the changes of the PageState and there is a need for them to update their view based on the PageState.
Therefore, an intuitive solution would be observer pattern. In which we have the components that subscribe to the changes of the dynamic state be the Observer, while the target dynamic state would be the Observable object.
Nonetheless, as the complexity of the UI increased, the original structure is not enough to solve the reactive behavior as some components would have a need to subscribe to multiple dynamic states, while simple observer pattern only allows
the observer to subscribe to one observable object because implementing Observer <T> and Observer <U> at the same time is not allowed in Java.
In the end, we decided to create mediator classes named Listeners which subscribe to one specific dynamic state, and have the Component which originally need to subscribe to more than dynamic states depend on multiple Listeners.
However, the change of the static state should update the view for the Component.
Before introducing Listeners, the view update is specified in the Component itself, as now we pass the responsibility of subscribing to the Listeners, the Listeners would then be in charge of
the update of the the Component’s view. To equip Listeners with the ability to update the view, the Component created a CallBack and passed it as argument when creating the Listeners.
3.3.3.2. Implementation
Step 1. Create CallBack object inside the UiComponent. In the CallBack, we specify how the view of the UiComponent is supposed to change on the update of the dynamic state. Then construct a Listener with the CallBack being the argument to finish the process of subscribing. The picture below shows the dependency between them.
Step 2. When the dynamic state is updated, it will then inform all the Listeners, and the Listeners would consequently change the view of the UiComponent by triggering the CallBack. The following two diagrams show the flow.
Flow
Sequential diagram

dynamic state, in some Component, multiple subscription is not needed, we keep it as normal observer pattern. Refer to sidebar implementation for the example of subscribing to only one dynamic state.
3.3.3.4. Structure for individual Ui page
The following paragraphs provide the class diagrams of the three Ui pages. Developers can refer to these diagrams to scale the system.
ScheduleUi

FlashcardUi
QuizUi

3.4. Logic component
API :
Logic.java
-
Logicuses theStudyBananasParserclass to parse the user command. - This results in a
Commandobject which is executed by theLogicManager. - The command execution can affect the
Model(e.g. deleting a task). - 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 task 1") API call.

❗ Note: The lifeline for DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
3.5. Storage component
API : Storage.java
The Storage component,
- can save
UserPrefobjects in json format and read it back. - can save the
Schedule,FlashcardBankandQuizRecordsdata in json format and read it back.
3.5.1. Overall Structure
StudyBananas supports 3 different systems, namely Schedule, FlashcardBank and Quiz. Each of these
systems needs to store their own type of data. Compared to the original AddressBook3 where AddressBookStorage is the
interface that exposes the functionality to save and read the data from the storage file, StudyBananas storage
is more complicated with the existence of these 3 distinct systems.
Therefore, our team decides to split the
storage such that each system has their own storage interface, including ScheduleStorage, FlashcardBankStorage and
QuizRecordsStorage, that is in charge of saving and reading their own data from their respective storage file as seen from the figure below
. The Storage
component then contains these 3 storage systems as well as the UserPrefs storage and exposes the storage functionality
to other components such as Logic to modify the stored data.

3.5.2. Analysis
- Pros:
- It allows StudyBananas to have one high-level
Storagecomponents that interacts with other high-level components in the architecture level. - Interface Segregation Principle is preserved as each system storage only needs to deal with the reading and saving data of its own system.
-
Open-Closed Principle is preserved for
Storagecomponent. If more components are added, developers only need to extend by creatingXYZStorageand add a new attribute and methods toStoragecomponent instead of modifying existingXYZStorage.
- It allows StudyBananas to have one high-level
- Cons:
- If there is a common data that is shared between different systems and it is modified,
Logicneeds to have multiple calls of save to each systems have to update the data in different systems.
- If there is a common data that is shared between different systems and it is modified,
3.6. Common classes
Classes used by multiple components are in the seedu.studybananas.commons package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1. Support multiple DateTime format feature
4.1.1. Implementation
StudyBananas is optimized for command line users, and supports multiple formats of input date time (see add-a-task to find out all the time formats that StudyBananas supports). As the number of supported date time format increases, a scalable structure is then proposed. The picture below describes the overall structure.
Each Format implements check method from DateFormat interface. The check method checks if the input string
matches the pattern of the Format class. If the format matches, it would transform input string into LocalDateTime object;
otherwise it throws TimeFormatException.
The TimeFormatChecker is the API that communicates with DateTime class.
It contains all the available Formats, and helps DateTime check if the input string matches anyone of the Format.
If the input string matches one of the Formats, it takes advantage the DateFormat#check to map the string into LocalDateTime
for DateTime object. The following paragraph provides the step-by-step guide to support one more time format for StudyBananas.
Step 1. Create a Format class for the desired date format, and have it implement the DateFormat interface.
Then, specify the check logic in the check method.
Step 2. Add the new DateFormat into the check list residing in the TimeFormatChecker class.
4.1.2. Design consideration:
4.1.3. Aspect: How is multiple time format implemented
-
Current choice:
- Pros: It segregates the check logic from the
DateTimeformat. In a sense, this is a good practice of Single responsibility principle as the check process is divided into three classes. Each is only in charge of one task. - Cons: As the supported format increases, a lot more classes and tests will need to be maintained. The efforts required to put into the maintenance is the major overhead.
- Pros: It segregates the check logic from the
-
Alternative choice : Have an almighty checker class which checks all the available formats in one class instead of creating multiple classes for multiple supported
Format- Pros: It reduces the number of classes and tests to maintain, and if the logic inside the
Checkerclass is written neatly, it would be easy to test as all format should go through similar happy paths. - Cons: Harder to debug and would have a much fatter class compared to the current implementation.
- Pros: It reduces the number of classes and tests to maintain, and if the logic inside the
4.2. Edit Task feature
4.2.1. Implementation
The edit mechanism is facilitated by Schedule, which contains a UniqueTaskList such that each TASK’s information can be modified
after its creation and addition into the UniqueTaskList. It implements this following feature:
-
Schedule#setTask()— Replaces an existing task in theSchedulewith a new task.
This operation is exposed in the ScheduleModel interface as ScheduleModel#setTask().
Given below is one example usage scenario and how the edit task mechanism behaves at each step.
Note: The attributes of the TASKs in this examples are omitted if they are not changed due to the edit task
functionality. Given below is the class diagram of TASK model for a better understanding of this example.
Step 1. The user launches the application. The SCHEDULE contains UniqueTaskList, which is initialized from the saved
TASKs in the JSON file schedule.json locally (see Storage component)
For example, the user already has 3 TASKs saved in the initial SCHEDULE as seen below.
Step 2. The user adds a new TASK into the schedule using the add task command.
This TASK is assigned the index 4 in the SCHEDULE
Step 3. The user now wants to change the description of the currently added TASK, and decides to edit the description of the TASK by entering the command edit task 4 d: Quiz 3 about Boolean Algebra.
The edit task command will be parsed by the Parser and create a ScheduleEditCommand object.
ScheduleEditCommand#execute() creates a new TASK object, containing the updated information fields. For the fields that is not specified in the edit task command, such as title in the example, the new TASK
takes the existing fields of the to-be-replaced TASK (note how the same title object is shared between task4 and editedTask4 as seen below).
Step 4. ScheduleModel#setTask() is then called to replace task4 with editedTask4 in Schedule.

ScheduleEditCommand#execute() creates a new TASK sharing some of the attribute object with the to-be-replaced TASK. Then ScheduleModel#setTask() sets the to-be-replaced TASK with the newly created TASK at index 4 of the SCHEDULE.The following sequence diagram shows how the edit task functionality works:
4.2.2. Design consideration:
Aspect: How edit task executes
-
Alternative 1 (current choice): Creates the new edited task object to replace the to-be-replaced task object.
- Pros: Update the
SCHEDULEby modifyingUniqueTaskListconsistently throughout the program so that side-effects, such as the existence of 2 different versions ofSCHEDULE, can be avoided. - Cons: May have performance issues in terms of memory usage as the replaced task object still remains in the memory. However, this is not a big issue as Java supports automatic memory management and the run-time memory usage of the program is not large.
- Pros: Update the
-
Alternative 2: Mutates the
TASKobject itself in theSCHEDULEat the corresponding index.- Pros: Will use less memory as there is no new creation of
TASKobject. - Cons: May result in side-effects such as there are out-of-dated versions of
SCHEDULEthroughout the program.
- Pros: Will use less memory as there is no new creation of
4.3. Quiz with storage of answers feature
4.3.1. Implementation
The proposed quiz with storage of answers mechanism is facilitated by Quiz and QuizModelManager, which implements the QuizModel interface.
It makes use of an array of answer strings as an attribute, stored within a Quiz object as userAnswers.
Additionally, it implements the following core operations with Quiz, which is called by QuizModelManager:
-
QuizModelManager#start(Quiz quiz)— Starts the quiz by initiating the quiz object in the model, iterating through the associated flashcard set and showing the first question in the flashcard set. The presence of at most one quiz object ensures that at most one quiz running at a time. -
QuizModelManager#hasStarted()— Checks if a quiz has started. This prevents multiple quizzes from running concurrently. -
QuizModelManager#tallyScore(boolean isCorrect)— Tallies the score after each answer is shown, depending on user’s judgement of correctness. -
QuizModelManager#getQuestion()— Obtains the question of the next flashcard in the flashcard set. -
QuizModelManager#getAnswer()— Obtains the answer of the next flashcard in the flashcard set. -
QuizModelManager#stopQuiz()— Stops the quiz. This method is called at the end of the flashcard set iteration. -
QuizModelManager#cancelQuiz()— Cancels the quiz. This method is called when the user cancels the quiz before reaching the end of the flashcard set. -
QuizModelManager#getQuizRecords(FlashcardSetName name)— Fetches the quiz score based on the associated flashcard set’s name. The score includes:- the number of correct answers out of the total score within the flashcard set, and percentage scored.
- the set of questions, the corresponding correct answers and the answers provided by the user
- whether each question was answered correctly.
These operations are as exactly written in the QuizModel and Model interface.
4.3.2. Usage Scenario
Given below is an example usage scenario and how the quiz with storage of answers mechanism behaves at each step.
Step 1. The user launches the application and starts the quiz for a non-empty, valid flashcard set.
As a result, it creates a QuizModelManager object and a StartCommand object.
Assume the flashcard set contains only two flashcards for simplicity.
The call to StartCommand#execute() from Logic will allow the Quiz to be initialized with the initial quiz state with default values for score,
the currentIndex pointing to the index of the first flashcard,
and the current command result being the first question through the call of Quiz#getQuestion().
The Quiz is saved into the QuizModelManagerobject as an attribute named quiz.
Step 2. The user executes ans:<answer> command to submit their answer to the question.
The AnswerCommand object created calls Quiz#saveAnswer(),
storing their answer into the userAnswers array attribute in Quiz
for the question before moving on to the correct answer through the call of Quiz#getAnswer().
The currentIndex attribute is incremented at this stage to point to the next flashcard.
Step 3. After viewing the answer, the user executes either c or w to indicate whether the question is answered correctly.
This creates either a CorrectCommand or WrongCommand object.
In the case of the CorrectCommand class below, the call to CorrectCommand#execute()
calls the Quiz:tallyScore() method through the interaction with QuizModel.
This increments the pointsScored attribute in quiz. Also, the next question is fetched through
the call to Quiz:getQuestion().
The following sequence diagram shows how this step works:

The object created will check if the currentIndex (updated in the previous step)
is within bounds to obtain the next flashcard.
In the current scenario, the question of the next flashcard is fetched and displayed
by calling the Quiz:getQuestion() method,
through QuizModelManager, during the execution of CorrectCommand:execute().
Step 4. Assume that the user has reached the end of the flashcards as shown below:
From the CorrectCommand:execute() / WrongCommand:execute() operation,
the QuizModelManager:stopQuiz() operation will be called.
This stops the quiz by removing the Quiz object stored in the quiz
attribute of QuizModelManager.
This leads to also calling the Quiz:toString() operation to show the quiz score and statistics.
The following activity diagram summarizes what happens when a user executes a new command:
4.3.3. Design consideration:
Aspect: How quiz with storage of answers executes
-
Current choice .
- Pros: Easy to implement.
- Cons: May have performance issues in terms of memory usage. {more aspects and alternatives to be added}
4.4. Sidebar view
4.4.1. Implementation
Sidebar view is implemented with the dynamic state structure (see Dynamic State) with SingletonUiState being the Observable object and MainWindow and SidebarTab being the Observers. As MainWindow and SidebarTab do not subscribe to other dynamic states. The listener is omitted here. The SingletonUiState is designed to be singleton, and default value SCHEDULE is assigned to it when the application is launched; Both MainWindow and SidebarTab implement the Observer interface and specify how their view should be changed in the update method. The list below describes how Observer pattern is adopted here.
-
Observable#register(Observer o)— Register a certain Observer to an Observable object, after registration, the observer object will be notified on any update of the Observable object. -
Observable#inform()— When the observable object is modified, use this method to inform all the subscribed observers. -
Observer#subscribe(Observable o)— Help the Observer class subscribes to an Observable Object. -
Observer#update()— This is the API for the Observer object to modify the Observable object and further helps inform all the subscribers.
The concrete implementation of these methods lies in the MainWindow, SidebarTab, and SingletonUiState, with MainWindow and SidebarTab being Observer and SingletonUiState being Observable
Given below is an example usage scenario and how the sidebar view mechanism behaves at each step.

4.4.2. Design consideration:
- Multiple Ui components rely on the unique
UiState. This is the intuition for Singleton. - Many components should be updated according to the changes of
UiState, it makes sense to build it using Observer pattern.
5. Documentation, logging, testing, configuration, dev-ops
6. Appendix: Requirements
6.1. Product scope
Target user profile:
- is a student, at upper secondary or tertiary education level
- has a need to keep track of study tasks and test their understanding of what is learnt
- prefers desktop apps over other types
- can type fast
- prefers typing to mouse interactions
- is reasonably comfortable using CLI apps
Value proposition:
- manage study tasks and test learnt knowledge faster than a typical mouse/GUI driven app
- centralize all study tasks and set up focused study sessions in one place
6.2. User stories
Priorities: High (must have) - * * *, Medium (nice to have) - * *, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
* * * |
Student | take advantage of the flashcard learning technique | memorize important facts/parts of the notes more efficiently and organizedly. |
* * * |
Learner who takes advantage of flashcard learning | be able to create custom flashcards | store my notes in the form of flashcards which optimises my flashcard learning. |
* * * |
User | delete my flashcards which are no longer in use | manage my own flashcards. |
* * * |
Student who learns by tests | test myself | learn more effectively. |
* * * |
Hard-working flashcard-learning user | create tests with the flashcard notes created by myself | see how good my learning outcome is. |
* * * |
User who learns by quizzing his/herself a lot | look back on my quiz attempts | evaluate how much more efforts I need to put in the section. |
* * * |
Student who regularly revises my concepts using flashcards | see the detailed answering history for my past quiz attempts | evaluate which concepts are still unclear to me and spend more time on those. |
* * * |
Student who regularly revises my concepts using flashcards | see my quiz statistics | know which part I do well and where I need improvement on in an objective manner. |
* * * |
Student who has tons of homework and exams | have a to-do list that organizes my study plan | plan my schedule more effectively. |
* * * |
Student who has a lot of homework and assignments | create a homework to-do list | keep track of what tasks I need to complete. |
* * * |
Student who frequently forgets my own homework and assignments | list out all the homework | view what to do. |
* * * |
Student who wants to look up certain homework and assignments | search or filter the list of homeworks and assignments | see the information for a specific homework. |
* * |
Savvy learner who wishes to track my study sessions | schedule my study plan | play myself more effectively. |
* * |
Savvy learner who wishes to track my study sessions | put my todo task in my schedule | plan my todo tasks more organizedly without missing any deadlines. |
* * |
Extremely organised learner | have a timer which runs during the scheduled period of time | make the best use of my time |
* * |
Student who organises the schedule carefully | leave feedback for each of my study session | know my learning efficiency during each session and make my new plans based on it. |
* |
Super busy student | have AI to schedule my todo lists based on my past studying statistics automatically for me | rely on the AI to make the best use of my time. |
6.3. Use cases
(For all use cases below, the System is the StudyBananas and the Actor is the user, unless specified otherwise)
Use case: UC01 Create a set of flashcards
MSS:
- User adds a new empty set of flashcards with a given name.
- User UC02 create and add an individual flashcard into a set
- Repeat 2 until all flashcards for the set are added.
Use case ends.
Extensions:
- 1a. Missing parameter - empty set name.
- a1. StudyBananas shows a missing parameter error message.
Use case ends.
- a1. StudyBananas shows a missing parameter error message.
Use case: UC02 Create and add an individual flashcard into a set
MSS:
- User defines the question and answer of the flashcard.
- User UC03 see all existing flashcard sets .
- User adds the flashcard to the set using the flashcard set index.
Use case ends.
Extensions:
- 1a. Missing parameter - question, answer or index of the flashcard set.
- a1. Shows missing parameter error message.
Use case ends.
- a1. Shows missing parameter error message.
Use case: UC03 See all existing flashcard sets
MSS
- User requests for the list of flashcards.
- StudyBananas shows the list of flashcards.
Use case ends.
Use case: UC04 Delete a flashcard set
MSS:
- User UC03 see all existing flashcard sets.
- User enters the index to delete the set.
- StudyBananas deletes the specified flashcard set.
Use case ends.
Extensions:
- 1a. There are no existing flashcard sets.
Use case ends. - 2a. Invalid index
- a1. StudyBananas shows an error message.
Use case ends.
- a1. StudyBananas shows an error message.
Use case: UC05 See all flashcards in a flashcard set
MSS:
- User UC03 see all existing flashcard sets .
- User requests for the list of flashcards using a given flashcard set index.
- StudyBananas shows the list of flashcards for the requested flashcard set.
Use case ends.
Extensions:
- 1a. Flashcard set is not present at entered index.
- a1. StudyBananas shows an error to indicate the invalid index.
Use case ends.
- a1. StudyBananas shows an error to indicate the invalid index.
Use case: UC06 Delete an individual flashcard from a set
MSS:
- User UC05 see all flashcards in a set.
- User enter the index of the set and the individual flashcard to delete it.
- StudyBananas deletes the specified flashcard.
Use case ends.
Extensions:
- 1a. The list is empty.
Use case ends. - 2a. The given index is invalid.
- a1. StudyBananas shows an error message.
Use case resumes at step 2.
- a1. StudyBananas shows an error message.
Use case: UC07 Quiz of flashcard set (no storage of answer)
MSS
- User requests a quiz of a given flashcard set.
- StudyBananas shows the first question in the flashcard set.
- User manually answers the question.
- User flips the flashcard to check the answer.
- User indicates whether the input answer is correct or incorrect.
- StudyBananas loads the next flashcard.
Step 2 - 6 are repeated until reaching the end of the flashcard set, or the User wants to stop the quiz halfway.
Use case ends.
Extensions
- 2a. The flashcard set is empty.
Use case ends. - 2b. The flashcard set does not exist.
- 2b1. StudyBananas shows an error message.
User case ends.
- 2b1. StudyBananas shows an error message.
- 5a. The answer indicator is invalid.
- 5a1. StudyBananas shows an error message.
User case resumes at step 5.
- 5a1. StudyBananas shows an error message.
- *a. At any time, User chooses to cancel the quiz.
- *a1. StudyBananas requests to confirm the cancellation.
- *a2. User confirms the cancellation.
Use case ends.
Use case: UC08 Quiz of flashcard set (with storage of answer)
MSS
- User requests a quiz of a given flashcard set.
- StudyBananas shows the first question in the flashcard set.
- User keys in their answer to the question.
- User flips the flashcard to check the answer.
- User indicates whether the input answer is correct or incorrect.
- StudyBananas stores the answer to each question and whether the answer was correct.
- StudyBananas loads the next flashcard.
Step 2 - 6 are repeated until reaching the end of the flashcard set, or the User wants to stop the quiz halfway.
Use case ends.
Extensions
- 2a. The flashcard set is empty.
Use case ends. - 2b. The flashcard set does not exist.
- 2b1. StudyBananas shows an error message.
Use case ends.
- 2b1. StudyBananas shows an error message.
- 5a. The answer indicator is invalid
- 5a1. StudyBananas shows an error message.
User case resumes at step 5.
- 5a1. StudyBananas shows an error message.
- *a. At any time, User chooses to cancel the quiz.
- *a1. StudyBananas requests to confirm the cancellation.
- *a2. User confirms the cancellation.
Use case ends.
Use case: UC09 Add a task to the schedule
MSS
- User requests to add a new task to the schedule.
- StudyBananas adds the task to the task schedule.
Use case ends.
Extensions
- 1a. User inputs missing parameter.
- a1. StudyBananas displays an error message specifying missing paramater.
Use case ends.
- a1. StudyBananas displays an error message specifying missing paramater.
- 1b. User inputs wrong format of parameter.
- b1. StudyBananas displays an error message specifying the wrong format of the respective parameter.
Use case ends.
- b1. StudyBananas displays an error message specifying the wrong format of the respective parameter.
Use case: UC10 Delete a task
MSS
- The user UC12 view all tasks.
- The user deletes a task at a specified index.
- StudyBananas deletes the task.
Use case ends.
Extensions
- 2a. Invalid task’s index specified
- 2a1. System signals to the user that the task’s index is invalid.
Use case ends.
- 2a1. System signals to the user that the task’s index is invalid.
Use case: UC11 Search for tasks
MSS
- The user search for a task with keywords.
- StudyBananas shows the filtered list with the matching keywords.
Use case ends.
Use case: UC12 View all tasks
MSS:
- User requests to view all the tasks.
- StudyBananas shows all the tasks.
Use case ends.
Use case: UC13 View quiz score and past attempt
MSS:
- User requests to UC03 see all available flashcard sets
- User requests for the score and past attempt of a quiz regarding a flashcard set using a given flashcard set index
- StudyBananas shows the score and most recent past attempt for the requested flashcard set.
Use case ends.
Extensions:
- 2a. Flashcard set is not present at entered index
- a1. StudyBananas shows an error to indicate the invalid index
Use case resumes at step 2.
- a1. StudyBananas shows an error to indicate the invalid index
- 3a. Flashcard set has not been quizzed yet
- a1. StudyBananas shows an error to indicate that flashcard set has not been quizzed
Use case ends.
- a1. StudyBananas shows an error to indicate that flashcard set has not been quizzed
6.4. Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11or above installed. - Should work without requiring an installer.
- The system should work on a 64-bit environment.
- The system should start up in no more than 2 seconds.
- The system should response to user input in less than 1 second.
- The product should be for a single user.
- The product should be usable by a student who has little to much experience in using computer.
- An 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.
- The data should be stored locally.
6.5. Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- CLI: Command Line Interface
- GUI: Graphical User Interface
- Flashcard: An object containing a question and the corresponding answer.
- Flashcard Set: A set of flashcards relevant to a specific topic.
6.6. Product survey
We have done up a product survey to find out accurately whether our project has met its non/functional requirements. Below are the summarised result:
Liked features
- The product is attractive in helping students with their study plans, and recapping their concepts.
- GUI is rather aesthetic looking, pleasing to the eyes.
- The available commands are intuitive, and are easy to use and remember.
Room for Improvement
- A dark mode can be included. Some users prefer a GUI with dark mode.
- More features can be integrated, eg undo/redo. These features can be included in version 2.0.
7. Appendix: Instructions for manual testing
Given below are instructions to test the app manually.
7.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 tasks, flashcards and quiz records. The window size is fixed.
-
7.2. Commands for manual testing
Note: For all commands except for general ones, only quiz mode commands are allowed when a quiz has started.
7.2.1. SCHEDULE commands
| Action | Format, Examples |
|---|---|
Add TASK |
add task <T:title> [d:description] [t:time] [dur:duration] e.g. add task T:CS2103T d:iP submission t: 2020-09-17 23:59
|
List TASKs |
list task |
Delete TASK |
delete task <index> e.g., delete task 6
|
Search for TASKs |
search task <keywords> e.g., search task CS2103T deadlines
|
Edit TASK |
edit task <index> [T:title] [d:description] [t:time] [dur:duration] e.g. edit task 1 d: Debug remaining errors dur: 60
|
Add TASK
-
Adding a task while all tasks are being shown
-
Prerequisites: List all tasks using the
list taskcommand. The task CS2103T with the same description and time should not exist yet. -
Test case: Enter
add task T:CS2103T d:iP submission t: 2020-09-17 23:59
Expected: A new task is created in the task list at the bottom, with title “CS2103T”, description “iP submission” and time “17 Sep 2020, 11:59PM”. The task list indexes should remain the same. However, after the entry of this command again, an error message appears, stating that this task already exists in StudyBananas. -
Test case: Enter
add task T:
Expected: No task is added. Error details shown in the pop-up saying task title must not be blank. Task list remains the same. -
Other incorrect delete commands to try:
add task
Expected: Invalid command format error.
-
List TASKs
-
Listing tasks in StudyBananas
- Test case: Enter
list tasks
Expected: The task list displays all tasks currently in StudyBananas. Deleted tasks will not be displayed.
- Test case: Enter
Delete TASK
-
Deleting a task while all tasks are being shown
-
Prerequisites: List all task using the
list taskcommand. Multiple tasks in the list. -
Test case:
delete task 1
Expected: First task is deleted from the list. Details of the deleted contact shown in the green pop-up. -
Test case:
delete task 0
Expected: No contact is deleted. Error details shown in the red pop-up. No change in the task list. -
Other incorrect delete commands to try:
delete task,delete task x,...(where x is larger than the list size)
Expected: Similar to previous.
-
Search for TASKs
-
Finding tasks by keywords
-
Prerequisites: List all tasks using the
task listcommand. Existing tasks include CS2103T and Job. -
Test case: Enter
search task CS2103T deadlines
Expected: Finds all tasks with the same keywords. A list of tasks will be displayed by StudyBananas. -
Test case: Enter
search task
Expected: An error message appears, stating that the command format is invalid.
-
Edit TASK
-
Editing a task while all tasks are being shown
-
Prerequisites: List all tasks using the
list taskcommand. -
Test case: Enter
edit task 1 d: Debug remaining errors dur: 60
Expected: The first task in the currently displayed list of tasks is edited to have the description “Debug remaining errors” and duration of 60 minutes. The task list should remain listed in the original order. -
Test case: Enter
edit task 1
Expected: No task is edited. Error details shown in the red pop-up. Task list remains the same. -
Other incorrect edit commands to try:
edit taskandedit task random
Expected: Similar to previous.
-
-
Editing a task while no tasks are shown
-
Prerequisites: Use the
search taskcommand to find tasks that does not match any keywords in StudyBananas. A blank task list should be displayed. -
Test case:
edit task 1 T:change title
Expected: No task is edited. Error details shown in the pop-up as invalid index. Task list remains the same.
-
7.2.2. FLASHCARD commands
| Action | Format, Examples |
|---|---|
Add FLASHCARDSET |
add flset <name:setname> e.g., add flset name:Japanese
|
Delete FLASHCARDSET |
delete flset <setindex> e.g., delete flset 1
|
List FLASHCARD in a specified set |
list fl <setindex> e.g., list fl 1
|
Add FLASHCARD in a specified set |
add fl <flset:setindex> <q:question> <a:answer> e.g., add fl flset:2 q:Is earth flat? a:Maybe!
|
Delete FLASHCARD in specified set |
delete fl <flset:setindex> <fl:index> e.g., delete fl flset:1 fl:1
|
Add FLASHCARDSET
-
Adding a flashcard set while all flashcard sets are being shown
-
Test case: Enter
add flset name:Japanese
Expected: A new flashcard set is created in the flashcard set list at the bottom, with the name “Japanese”. The flashcard set indexes should remain the same. However, after the entry of this command again, an error message appears, stating that this flashcard set already exists in StudyBananas. -
Test case: Enter
add flset name:
Expected: No flashcard set is added. Error details shown in the result display saying flashcard set name must not be blank. Flashcard set list remains the same. -
Other incorrect delete commands to try:
add flset
Expected: Invalid command format error, error details are shown.
-
Delete FLASHCARDSET
-
Deleting a flashcard set while all flashcard sets are being shown
-
Test case:
delete flset 1
Expected: First flashcard set is deleted from the list. Details of the deleted flashcard set shown in the result box. -
Test case:
delete flset 0
Expected: No flashcard set is deleted. Error details shown in the result display. No change in the flashcard set list. -
Other incorrect delete commands to try:
delete flset,delete flset x,...(where x is larger than the list size)
Expected: Similar to previous.
-
List FLASHCARD in a specified set
-
Listing tasks in StudyBananas
-
Test case: Enter
list fl flset:1
Expected: The flashcard table displays all flashcards currently in the specified flashcard set StudyBananas. Deleted flashcards will not be displayed. -
Test case: Enter
list fl flset:0
Expected: Error message displayed on the result box stating index is invalid. -
Test case: Enter
list fl flset:orlist fl flset:x(where x is larger than the list size)
Expected: Similar to previous.
-
Add FLASHCARD in a specified set
-
Adding a flashcard in a flashcard set
-
Test case: Enter
add fl flset:1 q:Is Earth flat? a:Maybe
Expected: A new flashcard is created in the flashcard table at the bottom, with the specified question and answer. The flashcard set and flashcard indexes within the set should remain the same. However, after the entry of this command again, an error message appears, stating that this flashcard already exists in StudyBananas. -
Test case: Enter
add fl flset:1
Expected: No flashcard set is added. Error details shown in the result display saying flashcard question and answer must not be blank. Flashcard set and flashcard list remains the same. -
Other incorrect delete commands to try:
add fl
Expected: Invalid command format error, error details are shown.
-
Delete FLASHCARD in specified set
-
Deleting a flashcard from a flashcard set
-
Test case:
delete fl flset:1 fl:1
Expected: First flashcard is deleted from the flashcard table of the first flashcard set. Details of the deleted flashcard shown in the result box. -
Test case:
delete fl fl:0 flset:1
Expected: No flashcard is deleted. Error details shown in the result display. No change in the flashcard set or flashcard list. -
Other incorrect delete commands to try:
delete fl flset:,delete fl flset:x fl:x,...(where x is larger than the list size)
Expected: Similar to previous.
-
7.2.3. QUIZ commands
| Action | Format, Examples |
|---|---|
QUIZ flset |
quiz <flset:setindex> e.g., quiz flset:7. quiz <flset:setname> eg., quiz flset:Japanese. Available only in quiz mode: flip, <ans:answer>, c, w, cancel, refresh
|
QUIZ score flset |
quiz score <flset:setindex> e.g., quiz score flset:6 quiz score <flset:setname> e.g., quiz score flset:Economics
|
QUIZ flset
-
Starting a quiz
-
Prerequisites: No ongoing quiz. If so, an error message will appear in a red pop-up, prompting user to cancel the quiz or finish it.
-
Test case:
quiz flset:1orquiz flset:CS2103T
Expected result: Quiz starts and first question is shown. -
Test case:
flip,answer:answerwhen question is shown only
Expected result: Shows the correct answer and user answer, “answer”. -
Test case:
c,w
Expected result: Shows the next question. -
Test case:
flip,answer:answerwhen question and answer shown
Expected result: Error message saying command is not available at this time. -
Test case:
c,w
Expected result: Error message saying command is not available at this time. -
Test case:
refresh
Expected result: Green pop-up saying quiz is refreshed. -
Test case:
cancel
Stops the quiz.
-
QUIZ score flset
-
Viewing quiz score
-
Prerequisites: No ongoing quiz. If so, an error message will appear in a red pop-up, prompting user to cancel the quiz or finish it.
-
Test case:
quiz score flset:1orquiz score flset:CS2103T
Expected result: Quiz records for the flashcard set “CS2103T” is shown.
-
General commands
| Action | Format, Examples |
|---|---|
| View all available commands | help |
| Exit program | exit |
Viewing help
-
Getting help page
- Test case:
helpExpected: A new window appears with the help information.
- Test case:
Exiting the program
-
Exiting the program
- Test case:
exitExpected: The application closes.
- Test case:
7.3. Saving data
-
Dealing with missing/corrupted data files
- Open any one of the files,
schedule.json,flashcardbank.jsonorquizrecords.jsonwhich is located in thedatafolder and delete theids of at least one attribute of either a task, flashcard set or quiz score. After which start the application. Expected: The StudyBananas opened should display an empty GUI for the feature with its file modified, where no data for that feature exists in the application.
- Open any one of the files,