Developer Guide

Table of contents

1. Introduction

revisED is a CLI application that helps students to revise by allowing them to create flashcards, take quizzes, and keep track of their deadlines, tasks and any other important dates. The users can create different subjects, add different topics under a subject, and create different flashcards in the form of questions and answers under a topic. They can also take quizzes for the flashcards they have added and view the results.

This developer guide is for developers who wish to understand and/or develop reviseED further. This guide includes design, implementation, logging, testing, product scope, and other sections to help developers better understand the application.

Note the following symbols and formatting used in this document:

Symbols / Formatting Meaning
📝️️ NOTE: Important or additional information
⚠️ WARNING: Things to avoid or pay extra attention to
✔️ TODO: Things that should be but have not been done
Grey highlight Code or terms related to the code/application

2. Setting up the Project

This section guides you through the steps to setup the project on your computer.

📝️️ NOTE: This guide assumes you already have Java 11 or above installed on your computer. If you do not have it yet, follow the link to download and install it.

  1. Fork this repo and clone the fork to your computer. Alternatively, download the source code from here.
  2. Open a console in the folder where build.gradle resides, and run the command gradlew.bat run if you are using Windows or ./gradlew run if you are using Mac/Linux.
  3. If the setup is successful, you should see the greeting screen:
> Task :run
Hello from
                                    ___________
                                    |  __ |  _ \
 ____  ______      _____   ________ |  |__| | | |
|  __|/ __ \ \    / /| |  /  _____/ |   __| | | |
| |  |  __/ \ \__/ / | | /_____  /  |  |__| |_| |
| |   \___|  \____/  |_|/_______/   |_____|_____/

____________________________________________________________
Hello! I'm revisED
____________________________________________________________
____________________________________________________________
Alright, What can I do for you?
____________________________________________________________
____________________________________________________________
Type help for all available commands
____________________________________________________________

Alternatively, if you are using IntelliJ, follow the first step above, then:

  1. Configure the Intellij for JDK 11, as described here.
  2. Import the project as a Gradle project, as described here.
  3. Locate and click the run task under Tasks > application > run in the Gradle tool window.

3. Design

This section describes how revisED has been designed so that developers can better understand the designing of the code, with the help of visual aids.

The application has been broken down into different levels so that users would find it easy to navigate from one level to the next one. There are three levels within the application, and their hierarchy is ranked as shown below:

Exiting from the Topic level will result in the program running at the Subject level, while exiting from the Subject level allows the program to run at the Main level. The program can also access the Subject level from the main level, or the Topic level from the Subject level via user input.

Architecture

architecture

Figure 3 Architecture diagram for revisED.

The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.

Revised is the Main class and is responsible for:

The rest of the App consists of six packages:

More details for each package can be accessed in the sections below, or by clicking the links above.

3.1 Card Package

cardUML

Figure 3.1 UML class diagram for card package. The quizcard package is omitted.

The card package contains the main data structures that holds the most of the information of the application. It contains:

Each of the classes in the card package contains getters and setters for its own attributes.

3.1.1 Quizcard Package

QuizUML

Figure 3.1.1 UML class diagram for the quizcard package

The quizcard package stores the information relating to all quiz functionality in the application. It also starts the quizes and handles the updating of results. It consists of 4 classes:

3.1.2 Taskcard Package

TaskUML

Figure 3.1.2 UML class diagram for taskcard package

The taskcard package stores the information relating to all the tasks in the application. It consists of 4 classes:

3.2 command Package

The Command package consists of different classes that executes the various commands of the application due to user input, and is split into 4 packages, flashcard, subject, task and topic, as well as an abstract command class, that is a superclass of the various classes in the different packages. As mentioned in the introduction of the design segment of the developer guide, the program is split into 3 levels, namely the main level, the subject level, as well as the topic level. The subjectcommand package holds the information to allow the program to execute a user command at the main level, the topiccommand package holds the information to allow the program to execute a user command at the subject level, while the taskcommand and flashcardcommand packages holds the information to allow the program to execute a user command

Each of the sub-packages hold multiple classes that are a subclass of the Command class, and contains:

subjectcommand package

The subjectcommand package holds all the necessary classes for executing methods at the main level. The Class that will be created and executed depends on user input. A Class diagram of how the classes interact with each other in the subjectcommand package is shown below.

SubjectCommandClassDiagram

Figure 3.2.1 UML class diagram for subjectcommand package

The subjectcommand package holds the following classes.

AccessSubjectCommand

The AccessSubjectCommand class has 3 methods:

and is mainly used for entering the Subject level from the Main Level. This occurs when the execute() method of the AccessSubjectCommand is first run. It first decodes the full command of the user input, then accesses the subject level of the program. Different Subject class instances have different information contained in them, thus there exists multiple subject levels of the program, each subject class having their own subject level in the program. For example, if there are 2 subjects, like Maths and Science, then accessing the Subject level of the Maths instance is different from accessing the Subject level of the Science Subject, since both subjects contain different information. Accessing the different subjects depend on user input, which will be decoded in the execute() method in AccessSubjectCommand. The execute() method will then run the goToSubject() command, that will access the information available in the subject that is selected via user input.

The isExit() method determines whether the program exits. The AccessSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

For more information of the implementation of the AccessCommand Class, refer to 4.8 Accessing subjects/topics implementation.

AddSubjectCommand

The execute() method of the AddSubjectCommand decodes the user input, then adds a subject into the SubjectList, which title depends on the user input. For example, if the user input is add Maths, then the title of the Subject created in the SubjectList will be Maths. It also prints the title of the subject that is added to the SubjectList.

The isExit() method determines whether the program exits. The AddSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

For more information of the implementation of the AddCommand Class, refer to 4.7 Adding objects implementation .

DeleteSubjectCommand

The execute() method of the DeleteSubjectCommand decodes the user input, then deletes a subject based on the index the Subject currently in the SubjectList. For example, when the user input is delete 1, the program decodes the input, and deletes the first Subject in the SubjectList, which is at index 0 of the SubjectList.

The isExit() method determines whether the program exits. The DeleteSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

ExitSubjectCommand

The execute() method of the ExitSubjectCommand does nothing, but needed since this method was implemented from an abstract class.

The isExit() method determines whether the program exits. The ExitSubjectCommand isExit() method is hard coded to return true, so that when the isExit() command is run, the program will exit.

ExportSubjectCommand

The execute() method of the ExportSubjectCommand calls the export() method of the storage instance to export all data to the disk storage.

The isExit() method determines whether the program exits. The ExportSubjectCommand isExit() method is hard coded to return false, so that when the isExit() command is run, the program does not exit.

FindSubjectCommand

The execute() method of the FindSubjectCommand decodes the user input, then find subjects whose title contains the keywords the user input into the program. It then prints the title of the Subjects in the SubjectList whose title contains the keyword.

The isExit() method determines whether the program exits. The FindSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

HelpSubjectCommand

The execute() method of the HelpSubjectCommand prints a list of available commands at the main level of the program, for the user to understand the format of inputs, as well as types of input needed for execution.

The isExit() method determines whether the program exits. The HelpSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

ListAllSubjectCommand

The execute() method of the ListAllSubjectCommand groups different tasks and flashcards under each topic, and different topics under each subject, then prints an organized list of all the subjects, topics, tasks and flashcards.

The isExit() method determines whether the program exits. The ListAllSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

ListSubjectCommand

The execute() method of the ListAllSubjectCommand prints a list of all subjects in the SubjectList instance.

The isExit() method determines whether the program exits. The ListSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

QuizSubjectCommand

The execute() method of the QuizSubjectCommand decodes the user input, and initiates a quiz for the subject that the user requested for. For example, if the user enters quiz Maths, then the application starts a quiz for the Maths subject.

The isExit() method determines whether the program exits. The QuizSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

ResultSubjectCommand

The execute() method of the ResultSubjectCommand decodes the user input, and prints out the results of previous SubjectQuizzes for the subject. For example, if the user enters results Maths, then the application prints out the results of the previous SubjectQuizzes attempted by the user for the Maths subject.

The isExit() method determines whether the program exits. The ResultSubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

SorrySubjectCommand

The execute() method of the SorrySubjectCommand throws a FailedParseException, meaning the parser has failed to decode the user input. Then, the exception will result in the Ui printing the error back to the user.

The isExit() method determines whether the program exits. The SorrySubjectCommand isExit() method is hard coded to return false since the command does not exit the code.

SubjectCommand

The SubjectCommand class is an abstract class that contains a abstract execute() method as well as a isExit() method, and is a super class for all the commands in the subjectcommand package. This is to ensure that all other commands in the subjectcommand package can have the same method calls, and that execute() can be called on a SubjectCommand class, even if they are a subclass of the SubjectCommand class.

topiccommand package

The topiccommand package holds all the necessary classes for executing methods at the subject level. The Class that will be created and executed depends on user input. A Class diagram of how the classes interact with each other in the topiccommand package is shown below.

TopicCommandClassDiagram

Figure 3.2.2 UML class diagram for topiccommand package

The topiccommand package holds the following classes.

All classes in the topiccommand package works the same way as the ones found in the subjectcommand package, but it deals with the Topic class instead of the Subject class. Notably, there is a change in parameters, as the TopicCommand classes is missing the Storage parameter. This is due to the absence of ExportCommand in the TopicCommands, since we did not implement the export command for the subject level. The rest of the TopicCommands do not need the Storage parameter since none of the execute() methods of the Commands require it. For more information of the subjectcommand package, please refer to SubjectCommand .

taskcommand package

The taskcommand package holds all the necessary classes for executing methods at the subject level. The Class that will be created and executed depends on user input. A Class diagram of how the classes interact with each other in the taskcommand package is shown below.

TaskCommandClassDiagram

Figure 3.2.3 UML class diagram for taskcommand package

The taskcommand package holds the following classes.

The Classes in the taskcommand package is different from the ones found in the other command packages. This is because all the taskcommand Classes are parsed by the TopicParser, since they work at the Subject level, similar to the Topic Commands. Thus, they do not have their own Exit Commands, List Commands and Help Commands, since all those are handled by the Topic Commands.

There are 3 different Add Task Commands, due to the 3 different formats of the Tasks that the user can save, namely Event, Deadline and Todo. The rest of the Task Commands have similar functionality to the ones found in the subjectcommand package. For more information of the subjectcommand package, please refer to SubjectCommand .

flashcardcommand package

The flashcardcommand package holds all the necessary classes for executing methods at the topic level. The Class that will be created and executed depends on user input. A Class diagram of how the classes interact with each other in the flashcardcommand package is shown below.

FlashcardCommandClassDiagram

Figure 3.2.4 UML class diagram for flashcardcommand package

The flashcardcommand package holds the following classes.

All classes in the Flashcardcommand package works the same way as the ones found in the subjectcommand package, but it deals with the Flashcard class instead of the Subject class. Notably, there is a change in parameters, as the FlashcardCommand classes is missing the Storage parameter. This is due to the absence of ExportCommand in the FlashcardCommands, since we did not implement the export command for the subject level. The rest of the FlashcardCommands do not need the Storage parameter since none of the execute() methods of the Commands require it. Additionally, the flashcardcommand package is also missing a few classes such as the QuizCommand, ResultCommand and FindCommand classes. This is due to the fact that at the topic level, there are only flashcards in each topic, and it would not make sense to quiz one flashcard at a time, thus the absence of the implementation. For more information of the subjectcommand package, please refer to SubjectCommand .

3.3 List Package

This package contains different list classes used for managing a list of different card package objects. They are used to abstract the extra processing needed (if any) before or after interacting with the underlying list. The relationship between the classes is shown below.

ListClass

Figure 3.3.1 UML class diagram for list package

✔️ TODO: Delete method should also be implemented here (just like the add method) and be called to do the delete operations instead of doing it directly through the underlying list for better cohesion.

✔️ TODO: FlashcardList should also be created to manage the list of flashcards instead of directly operate on the ArrayList for better cohesion.

3.4 Parser Package

The parser package consists of all the classes that are necessary to parse the user inputs. These classes are responsible to understand what the useer has input, and take the necessary action.

This package consists of three classes:

-SubjectParser: This class parses all the user inputs at the main level. It deals with all the commands that relate to working with subjects, such as add and delete subjects.

-TopicParser: This class parses all the user inputs at the subject level. It deals with all the commands that relate to working with topics and tasks, such as adding and deleting topics or tasks.

-FlashcardParser: This class parses all the user inputs at the topic level. It deals with all the commands that relate to working with flashcards, such as adding and deleting flashcards.

The classes in this package directly communicate with the command package in order to execute the relevant commands.

3.5 Ui Package

The ui package deals with handling user input and printing all the system outputs on the command line. It consists of one class, Ui. This class is responsible to print all messages to the command line. The command classes call the methods in this class in order to print anything on the command line. This class also deals with printing any messages when exceptions are encountered.

3.6 Storage Package

There are two classes inside this package, both of which are inside Storage.java. The following diagram shows the relationship between the two classes.

StorageClass

Figure 3.6.1 UML class diagram for storage package

StorageBuilder

StorageBuilder class is a static inner class of the Storage class. It follows the builder pattern and its sole purpose is to create Storage instances. The builder pattern is used to deal with the decrease in clarity due to the increase of the number parameters. Every instance of the Storage class should be created through StorageBuilder, and this is enforced by disabling the public constructor of the Storage class.

Storage

Storage class handles every operation that involves data storage, including storing, loading, and exporting of application data. Storing of data only happens when the application exits while loading of data only happens when the application launches. On the other hand, exporting of data happens when the user runs export command.

4. Implementation

This section describes some noteworthy details on how certain features are implemented.

4.1 Storing data

Storage class stores the data following the same logical structure (subject -> topic) of the application to make the stored data more presentable to the user. Subject and Topic data are stored as nested directories, while Flashcard and Result data are stored in JSON format so that they are readable to the users and allows them to change the saved data manually. Gson library is used to create the json files. Task data are stored differently as text files due to legacy reason, but they are also readable and can be changed manually as well.

📝️️ NOTE: If the users modify the file contents with wrong syntax, the data in the affected files will not be loaded and empty data will be returned instead so that the application can still run.

An example of the structure mentioned is shown in the figure below.

data                            --> Data main folder
└── CS2113T                     --> CS2113T subject folder
    ├── Java                    --> Java topic folder under CS2113T subject
    │   ├── topicResults.json
    │   └── flashcards.json
    ├── subjectResults.json
    └── tasks.txt

Figure 4.1.1 Sample directory structure

File formats

One tasks.txt file is created under each subject folder, storing the tasks (Todo, Event, Deadline) data under that subject. An example of the file content is shown below.

T | 1 | someTodoTask                                    --> Todo task
D | 0 | someDeadlineTask | 11:59 PM 20 Dec 2020         --> Deadline task
E | 0 | someEventTask | 1:00 PM 10 Nov 2020             --> Event task

Figure 4.1.2 Sample tasks.txt content

The first column of data shows the type of task, where T corresponds to Todo task, D corresponds to Deadline task, and E corresponds to Event task. The second column shows if a task is completed, where 0 means not completed while 1 means completed. The third column shows the name of a task. Lastly, the fourth column shows the time and date of a deadline or event task.

Moving on, one subjectResults.json is created under each subject folder, and one topicResults.json is created under each topic folder. subjectResults.json stores the quiz results the users have obtained from doing quizzes under a subject, while topicResults.json stores the quiz results the users have obtained from doing quizzes under a topic. Both of the files have the same content format, and an example of the file content is shown below.

[
  {                                    --> Result record 1
    "score": 1.0,                      --> Score obtained
    "maxScore": 1.0,                   --> Maximum score that can be obtained
    "description": "Excellent"         --> Result description
  },
  {                                    --> Result record 2
    ...
  },
  ...
]

Figure 4.1.3 Sample subjectResults.json content

This content format is a result of converting a list of Result data into json form.

Lastly, one flashcards.json file is created under each topic folder, storing all the flashcard data the users have added under a specific subject and topic. An example of the file content is shown below.

[
  {                                            --> Flashcard 1
    "question": "x + y = 4. y = ? ",
    "answer": "4 - x"
  },
  {                                            --> Flashcard 2
    ...
  },
  ...
]

Figure 4.1.4 Sample flashcard.json content

Similarly, this content format is a result of converting a list of Flashcard data into json form.

Behavior

The implementation stores the data in a cascading manner, meaning that when a call to save topics is made, all the data under the topics will be saved. Similarly, when a call to save subjects is made, all the data under the subjects including topics will be saved. The behavior mentioned is shown in the diagram below.

StorageSaveSubjects

Figure 4.1.5 UML sequence diagram for storing subjects

StorageSaveTopics

Figure 4.1.6 UML sequence diagram for storing topics

As can be seen in figure 4.1.5, all the data is deleted from the disk before saving of data takes place. It is implemented this way to make sure the deletion of a subject or topic by the user is also saved. Otherwise, the subject or topic will not be deleted since the rest of the method calls only replace or create data.

✔️ TODO: As the amount of data grows larger, this saving algorithm can get very slow since it only saves the data when the application exits, not to mention the (most of the time) needless deletion of all data before each save. To speed up the process, the implementation can be changed such that data is saved right after each user command that involves data manipulation.

4.2 Loading data

For the data stored in json format, they are loaded using the same Gson library, whereas for the data tasks.txt, they are parsed line by line and converted into corresponding Task objects. The loading of data follows a similar cascading manner as saving, as can be seen in the diagram below.

StorageLoadSubjects

Figure 4.2.1 UML sequence diagram for loading subjects

StorageLoadTopics

Figure 4.2.2 UML sequence diagram for loading topics

Note that only Subject and Topic data are sorted; Result, Flashcard, and Task data still follow the added order. This is because subjects and topics are stored as directories, and the order of the directories loaded is not guaranteed by the Java, so the sorting is just to fix the inconsistency of the order. The rest of the data, on the other hand, is guarenteed to have the same order every time they are loaded, so they are not sorted.

4.3 Exporting data

The user can export all data of the application to the pre-defined export/data.json in the same directory where the application runs. An example of the file content is shown below.

[
  {                                                                  --> Subject 1
    "title": "CS2113T",                                                
    "topics": {
      "topics": [                                                    --> Topics under CS2113T subject
        {                                                            --> Topic 1
          "title": "Java",                                        
          "flashcards": [same as the content of flashcards.json],    --> Flashcards under Java topic
          "results": {
            "resultList": [same as the content of topicResults.json] --> Results under Java topic
          }
        },
        ...
      ]
    },
    "tasks": {                                                       --> Tasks under CS2113T subject
      "taskList": [
        {                                                            --> Task 1
          "description": "someTodoTask",
          "isDone": false
        },
        {                                                            --> Task 2
          "dateTime": {
            "date": {
              "year": 2020,
              "month": 12,
              "day": 20
            },
            "time": {
              "hour": 23,
              "minute": 59,
              "second": 0,
              "nano": 0
            }
          },
          "description": "someDeadlineTask",
          "isDone": false
        },
        ...                                                       
      ]
    },                            
    "results": {
      "resultList": [same as the content of subjectResults.json]    --> Results under CS2113T subject
    }
  },
  ...                                                               --> More subjects
]

Figure 4.3.1 Sample data.json content

This content format is a result of converting a list of Subject objects with populated data into json form.

✔️ TODO: Importing of the exported data is not yet supported, and it would make sense to implement it in the future versions. However, it may not be straightforward as type conversion is needed to convert the data into the right types (refer to Gson documentation for more details).

4.4 Parsing Commands

The parser package contains the following three classes which are responsible for making sense of the user input.

SubjectParser

The SubjectParser class parses the user inputs at the main level. The diagram below shows how the SubjectParser class is implemented.

SUbjectParser Figure 4.4.1 UML sequence diagram for subject parser

FlashcardParser

The FlashcardParser class parses the user inputs at the topic level. The diagram below shows how the FlashcardParser class is implemented.

FlashcardParser Figure 4.4.2 UML sequence diagram for flashcard parser

TopicParser

The TopicParser class parses the user inputs at the topic level. This class is implemented in a similar manner as the FlashcardParser and SubjectParser classes.

4.5 Quiz

The abstract quiz class contains a checkAnswer() method that checks the answer that the user had given with the correct answer of the quiz. If the user enters the correct answer, the existing score is incremented by one. Else, the contents of the flashcards and the incorrect answer provided by the user are transferred to the incorrectAnswers list. Once the user finished the quiz, the application would print the questions that the users did not answer correctly, along the the answer that was provided by the user.

Initiating a subject quiz

You can start a subject quiz by entering quiz NAMEOFSUBJECT. Subsequently, the application retrieves the QuizSubjectCommand after parsing the command and calls for the startQuiz method. The startQuiz method calls for the setupQuiz method checks for the presence of topics or flashcards. Else, the application throws the NoTopicException for the former, and the NoFlashcardException for the latter. If the topics have flashcards, then these are transferred to the SubjectQuiz class, while the maximum score of the quiz is set to be the total number of flashcards in the list of flashcards present in the SubjectQuiz class .

The application now returns to the startQuiz method and the current score of the quiz is set to zero. Subsequently, the application begins printing the questions from the flashcards and checks the answer that you provide. If you want to stop the quiz, use the stop command. The application will then print out the score that you obtain. If you complete the quiz then the application not only prints the score, but it also prints the incorrect answers from the quiz.

The following diagram shows how you can initiate the quiz for the Maths Subject.

first

Figure 4.5.1 UML sequence diagram for subject quiz

Initiating a topic quiz

Provided that you have used the subject NAMEOFSUBJECT command to access a subject,you can start a subject quiz by entering quiz NAMEOFTOPIC. Subsequently, the application retrieves the QuizTopicCommand after parsing the command and calls for the startQuiz method. This method class for the setupQuizmethod, which throws the NoFlashcardException for when the topic does not have any flashcards. The application then returns back to the startQuiz method. The implementation of the startQuiz method is similar to that of the SubjectQuiz class.

The following diagram shows how you can initiate the quiz for a topic speed under the Maths subject.

topic

Figure 4.5.2 UML sequence diagram for topic quiz

📝️ NOTE: For both the subject quiz and the topic quiz, the application only prints out the incorrectAnswer if the user has completed the quiz. If the user stops the quiz without completing it, then the application will only show the score obtained by the user.

4.6 Sorting tasks

The application sorts the tasks according to their dates and times. Tasks which are due soon are placed at the front while tasks which are due later are placed at the end of the task list. Todo tasks are placed at the end of the tasklist. Their LocalDateTime variables are assigned the LocalDateTimeMax value. This is to ensure that the sorting can be done for all tasks.

4.7 Results feature

Updating results

The updateResult method in the Resultclass updates the result for a given quiz by setting the score and the description. There are three categories of descriptions: Fail for getting a score which is lesser than half of the maximum score, Pass for obtaining a score above half of the maximum score and Excellent for getting the maximum score in a quiz.

4.7.1 Printing out the results for a subject

For the results of a subject , the printSubjectResults method in the Ui class checks if there are any results of previous subject quizzes for that particular subject.

sr

Figure 4.7.1 UML sequence diagram for requesting results of the Maths subject

4.7.2 Printing out the results for a topic

For the results of a topic, the printTopicResults method checks if the topic has any any results from previous topic quizzes. The user has to access the particular subject level to use this command.

tr

Figure 4.7.2 UML sequence diagram for requesting results of the Speed topic of the Maths subject

4.8 Adding objects

Each of the add commands have an execute() method. The execute() method for AddSubjectCommand add subjects into the subject list, the execute() method for AddTopicCommand add topics in a subject, while the execute() method for AddTodoCommand, AddDeadlineCommand and AddEventCommand adds tasks in a subject. subject.

Adding a subject

You can add a subject by entering add [SUBJECT_NAME]. The subject will be added to a SubjectList created when the program initialises. After the program initialises, the program will ask for user input. The Ui will read the user input using the readCommand() method, then the the SubjectParser will parse the command. Since the user input is add [TOPIC_NAME], the program will register it as a command to add a Subject, and will create a new AddSubjectCommand. This AddSubjectCommand is then passed back to the main function, where its execute() method will run. The execute method decodes the user input. If the [SUBJECT_NAME] is not a title of another Subject already on the list, it will create a new Subject, and add that new Subject created into the SubjectList that was created during initialisation of the program. The Ui will then print the adding of the Subject into the list. The program then returns to the main function, where it waits for next user input.

A Sequence diagram of adding a Subject Maths is shown below. AddSubjectSequenceDiagram

Figure 4.8.1 UML sequence diagram for adding a subject

Adding a topic/task

you can add a Topic by entering add [TOPIC_NAME]. Additionally, you can add a Todo task by entering todo [DESCRIPTION], add a Deadline task by entering deadline [DESCRIPTION] /by [TIME], and add an Event task by entering event [DESCRIPTION] /at [TIME]. This command can only be entered in the subject level of the program, which can be accessed using the command subject [SUBJECT_NAME]. The documentation of the implementation and how to access a subject can be found in 4.8 Accessing subjects/topics implementation.

Otherwise, adding topics and tasks follows the same implementation as adding a subject.

4.9 Accessing levels

Each of the access commands have an execute() method and a goToSubject()/goToTopic() method. The AccessSubjectCommand class allows users to access the subject level of a subject specified in the user input from the main level, while the AccessTopicCommand class allows users to access the topic level of a topic specified in the user input from a subject level.

Accessing a subject

You can access a subject by entering subject [SUBJECT_NAME]. The subject needs to be a subject that already exists in the list, and you can add the Subject into the SubjectList by using the add [SUBJECT_NAME] feature, elaborated further in 4.7 Adding objects implementation. For example, after adding a Subject CS2101, the CS2101 Subject can be accessed by entering access CS2101. The application first reads the command using the Ui class, then parses the user input using the SubjectParser class, similar to adding a subject. The program will register the user input as a command to access a subject. The SubjectParser will create a new AccessSubjectCommand class, and this class will be returned to the main function. The main program will run the execute() method of AccessSubjectCommand. The execute() method checks for subjects in the SubjectList whose title matches the [SUBJECT_NAME], and if a subject matches, the subject will be passed as a parameter to the goToSubject() method. The goToSubject() method will then have a loop that reads user inputs and parse these inputs to create new TopicCommand or TaskCommand classes to execute.

The sequence diagram of accessing a Subject Maths is shown below. AccessSubjectSequenceDiagram

Figure 4.9.1 UML sequence diagram for accessing a subject

Accessing a Topic

You can access a topic by entering topic [TOPIC_NAME]. The topic needs to be a topic that already exists in the list, and you can add the Topic into the TopicList of a Subject by using the adding a topic feature, elaborated further in 4.7 Adding objects implementation.

4.10 list all command

While the syntax of the list all command is the same on the main, subject and topic levels, there are 3 separate ListAllXYZCommands for each level. Although all 3 commands classes call Ui.printAll(subjects,activeSubject,activeTopic), the 3 classes are kept separate so that printAll() can recognise what object the user is accessing.

The following sequence diagram shows how you can proccess the list all command from the subject level.

ListAllTopicSequenceDiagram

Figure 4.9.1 UML sequence diagram for list all at topic level

If the list all command is given at the topic level, printTreeTopic() will check if each topic is the active topic each loop, instead of Ui.printAll checking each subject.

📝️ NOTE: This command uses unicode characters such as "├" and "└". You may consider changing the characters to ASCII characters only for the sake of compatibility.

5. Logging

We use java.util.logging package for logging. Whenever you need to use logging in a class, add this line

java
private static final Logger logger = Logger.getLogger(CurrentClass.class.getName());

to the start of the class to get a logger instance, where CurrentClass is replaced by the class name you are adding the logger to. Subsequently, you can use the logger instance created to start logging. To learn more about how logging works, read the official logging documentation.

The current configuration logs all the messages with log levels above FINE into a file (revisED.log) in the same directory where the application is run. You can find more details about the logging configurations (and change them or add more) in src/main/resources/logging.properties. For consistency, you should only change the behavior of logging via this file.

6. Documentation

All project documentations are put under the /docs folder. The following tools are used to write the documentations:

To learn how set the documentation website up and maintain it, follow the guide Using Jekyll for project documentation.

To convert the documents to PDF files for distribution, follow the guide Saving web documents as PDF files.

7. Testing

This section describes different types of tests used in the application and the ways to carry them out.

7.1 JUnit Tests

We use JUnit to write all unit tests and integration tests for the project. If you are new to JUnit, refer to the JUnit Tutorial.

All the JUnit Tests are located under src/test folder. To run all the tests available in the project, open a console in the project root directory and run gradlew.bat test if you are using Windows or ./gradlew test if you are using Mac/Linux.

Alternatively, you can run the test task under Tasks > verification > test in the Gradle tool window if you are using IntelliJ.

7.2 I/O Redirection Tests

We use I/O redirection to test the actual output of the application against the expected output using a set of different inputs.

To run the test, open a console in the text-ui-test folder under the project root and run runtest.bat if you are using Windows or ./runtest.sh if you are using Mac/Linux. If the test is successful, you will see the following message in the last line of the output.

Test passed!

If the test fails, you will instead see the following message in the last line of the output.

Test failed!

To see what goes wrong, you can compare the content of ACTUAL.txt and the content of EXPECTED.txt inside the same folder, where ACTUAL.txt contains the actual output of the application and EXPECTED.txt shows the expected output of the application given the inputs.

📝️️ NOTE: You can change the inputs in input.txt and the expected output in EXPECTED.txt if you would like to test more aspects of the application or if the input/expected output changes due to code modification.

7.3 Checkstyle

We use Checkstyle to check if all the developers comply to the coding standards. The rules and configurations can be found in checkstyle.xml under config/checkstyle folder in the project root. Refer to the official documentation to learn more about how to configure the rules.

To run the checks, open a console in the project root directory and run gradlew.bat checkstyleMain if you are using Windows or ./gradlew checkstyleMain if you are using Mac/Linux.

Alternatively, you can run the checkstyleMain task under Tasks > other > checkstyleMain in the Gradle tool window if you are using IntelliJ.

Appendix A: Product scope

This section describes the scope of the application. To be specific, the target audience and the uses and benefits of this application.

Target user profile

The targeted audience are university students , aged 18 - 25 who have access to a computer. The students must be familiar with applications that run on the command-line interface. Currently, this application is created for students who study in Singaporean universities.

Value proposition

This application aims to help students to keep track of their revision. Students should be able to revise their subjects effectively through this application by adding various questions and answers in the form of flashcards. After that, students can refer to the flashcards to revise the subjects. Furthermore, they can take quizzes and see if they grasp the topics or subjects well enough to attend their school based exams.

Students who find it hard to keep track of their assignments would also find this application useful since it lets the students add their tasks. The application then reminds the students regarding the upcoming tasks, which would prompt the students to prepare them.

Students who find it difficult to organise would find this app useful since it offers a one stop solution to manage both their revision and their upcoming tasks .

Appendix B: User Stories

This section summarises various user stories of this application in the table below.

Version As a ... I want to ... So that I ...
v1.0 new user add a flash card intuitively don't get put off by learning a new program
v1.0 long time user categorize the flashcards to different categories know where to look for which flashcard
v1.0 organised person see neat UI and flashcard organization will want to use the program
v1.0 student revise all my notes for different subjects do not have to use multiple applications/websites to revise
v1.0 long time user add flashcards efficiently can save time when need to add multiple flashcards
v1.0 long time user find a to-do item by name can locate a to-do without having to go through the entire list
v1.0 student do quizzes on the flashcards added can know how much I remember the content
v2.0 forgetful student be notified of assignments which are due in a week do not forget them
v2.0 new user see usage instructions can refer to them when I forget how to use the application
v2.0 CS student export all data into a readable format can import the data into another application I made
v2.0 normal user be able to view my data saved on the disk easily can do modify the data without launching the app
v2.0 long time user see all the subjects, topics, and number of flashcards I have added know what I have added

Appendix C: Non-Functional Requirements

The following are the requirements that the application should satisfy:

  1. The application should be easily maintainable when bugs and errors occur.
  2. The application should be scalable for possible future expansion of the project.
  3. The application should run on any mainstream OS as long as it has Java 11 or above installed.
  4. Application data should be portable so that it can be transferred between devices.
  5. The application should be easy to use or come with a detailed user guide/help for better user experience.
  6. The application should not crash when invalid or malicious user input is received.
  7. Users should be allowed to modify the saved data manually without causing disruption to the application operations.

Appendix D: Glossary

A

  1. AccessSubjectCommand - A command in the subjectcommand package which returns the subject that the user wants to access.
  2. AccessTopicCommand - A command in the topiccommand package which returns the topic that the user wants to access.
  3. AddDeadlineCommand - A command in the taskcommand package which adds a deadline task in the application.
  4. AddEventCommand - A command in the taskcommand package which adds an event task to the application.
  5. AddFlashcardCommand - A command in the flashcardcommand package which adds a flashcard in the application.
  6. AddSubjectCommand - A command in the subjectcommand package which adds a subject to the application.
  7. AddTodoCommand - A command in the taskcommand package which adds a todo task in the application.
  8. AddTopicCommand - A command in the topiccommand package which adds a topic to the application.
  9. Application - Refers to the revisED application which the user is using.
  10. attributes - variables in a class

B

  1. BaseList - An abstract class in the list package which all others lists inherit from.
  2. Builder Pattern - A methodology used in the Storage class to ensure that the clarity does not decrease even if the number of parameters increase.

C

  1. card - Package which contains the quizcard package, task package and the Flashcard,Topic and Subject classes.
  2. Checkstyle - Tool that checks the coding standards in the application.
  3. CLI - Command Line Interface
  4. Command - An abstract class in the command package which is inherited by all the command classes.
  5. command - A package which holds the 4 command packages: subjectcommand,topiccommand,taskcommand,flashcardcommand. This package is in charge of returning the relevant subject,task,topic or flashcard .

D

  1. DataLoadingException - An exception thrown if the application is not able to load data.
  2. DateTime - A variable in Event and Deadline classes which tracks the time and date at which the task has to be completed.
  3. Deadline - A class in the taskcard package which refers to a task with a deadline. Inherits from the Task class.
  4. DeleteFlashcardCommand - A command in the flashcardcommand package which deletes a flashcard from the application.
  5. DeleteSubjectCommand - A command in the subjectcommand package which deletes a subject from the application.
  6. DeleteTaskCommand - A command in the taskcommand package which deletes a task from the application.
  7. DeleteTopicCommand - A command in the topiccommand package which deletes a topic from the application.
  8. description - A variable in the Result class which describes the grade obtained during a quiz.
  9. description - A variable in the Task class which describes the task to be completed.

E

  1. Event - A class in the taskcard package which refers to an event. Inherits from the Task class.
  2. Excellent - A description for a quiz present in the Result class which states that the user obtained full marks for the quiz.
  3. Exception - A class which holds conditions that the application would throw in the event that the input entered is incorrect.
  4. exception - A package which holds all the exceptions used in the application. These exceptions are delcared as individual classes, all extending the Exception class.
  5. execute - A command in Command classes which executes the required action by the command.
  6. ExitFlashcardCommand - A command in the flashcardcommand package which allows the user to exit the topic level to return to the subject level.
  7. ExitSubjectCommand - A command in the subjectcommand package which allows the user to exit the application.
  8. ExitTaskCommand - A command in the taskcommand package which allows the user to exit the subject level to return to the main level.
  9. ExitTopicCommand - A command in the topiccommand package which allows the user to exit the subject level to return to the main level.
  10. export - A User Command to export the data to external file.

F

  1. Fail - A description for a quiz which states that the user failed the quiz.
  2. FailedParseException - An exception thrown in the SorrySubjectCommand if the application is not able to read the commands.
  3. FINE - A log level, which indicates the severity of the message.
  4. Flashcard - A class in the card package which instantiates the flashcard object.Contains the question and answer feature of the flashcard.
  5. FlashcardCommand - An abstract class that is inherited by all the other FlashcardCommand classes in the FlashCardCommand package.
  6. flashcardcommand - A package which holds the different FlashcardCommand classes.
  7. flashcardexception - A package which holds all the exceptions for methods related to flashcard operations.
  8. FlashcardParser - A class in the parser package which reads the user commands to call the relevant Flashcard command.
  9. FindSubjectCommand - A command in the subjectcommand package which finds the subject which the user requested for.
  10. FindTaskCommand - A command in the taskcommand package which finds the task which the user requested for.
  11. FindTopicCommand - A command in the topiccommand package which finds the topic which the user requested for.

G

  1. GSON - Used to create the Json files in the external data file.
  2. goToSubject- A method in the AccessSubjectCommand class which allows the application to transition to the Subject Level from the main level.
  3. goToTopic - A method in the AccessTopicCommand class which allows the application to transfer from the Subject Level to the Topic Level.
  4. GRADLE - An automated tool to build and compile the application.

H

  1. HelpSubjectCommand - A command in the subjectcommand package which lists all the commands in the Main level.
  2. HelpTopicCommand - A command in the topiccommand package which lists all the commands in the Subject level.

I

  1. isExit - A method which checks if the user wants to change levels/exit application. This method is implemented in all the command classes.
  2. incorrectAnswers - List present in the Quiz class which stores the questions that the user answered incorrectly, along with the answer provided by the user and the correct answer.
  3. InvalidFlashcardException - An exception thrown if a flashcard is not created using the question ; answer format.
  4. InvalidSubjectException - An exception that is thrown if the user does not add a title of a subject for the commands in the main level.
  5. InvalidTopicException - An exception thrown if the TopicCommands are used solely without a topic.
  6. I/O - Input/Output

J

  1. Jekyll - A software used by Github to create websites.
  2. JSON - Javascript Object Notation. A form of data representation used in the external data files.
  3. JUnit - A testing framework in Java that runs automated tests.

L

  1. list - A package which holds all the lists used in the application.
  2. ListAllFlashcardCommand - A command in the flashcardcommand package which lists all the items in the application in the topic level.
  3. ListAllSubjectCommand - A command in the subjectcommand package which all the items in the application.
  4. ListAllTopicCommand - A command in the topiccommand package which prints all the topics in the Subject level.
  5. ListFlashcardCommand - A command in the flashcardcommand package which lists all the flashcards in the application.
  6. ListSubjectCommand - A command in the subjectcommand package which lists all the subjects in the application.
  7. ListTaskCommand - A command in the taskcommand packagewhich lists all the tasks in the application.
  8. ListTopicCommand - A command in the topiccommand package which lists all the topics and tasks in the application.
  9. LocalDateTime - A class in Java which contains both the time and date of a given task.Used in Event and Deadline classes.
  10. LocalDateTimeMax- Maximum time available in the LocalDateTime library.
  11. loadFlashcards - Method in Storage class which loads the flashcards into the application.
  12. loadResults - Method in Storage class which loads the results into the application.
  13. loadTasks - Method in Storage class which loads the tasks into the application
  14. loadTopics - Method in Storage class which loads the topics into the application.
  15. Logging - Procedure of writing information to an external file, to track the flow of the program.

M

  1. maxScore - Maximum score obtainable from a quiz.Present in the Result class.
  2. Markdown - Syntax used in Github.

N

  1. NoFlashcardException - An exception thrown if a quiz is initiated for a subject or topic without flashcards.
  2. NoSubjectException - An exception thrown if the user requests for a subject that is not present in the application.
  3. NoTopicException - An exception thrown if the user requests for a topic that has not been added to the application.

P

  1. parser - A package which parses the user commands and initialises the necessary topics,subjects or tasks.
  2. Pass - A description for a quiz which states that the user passed the quiz.Present in the Result class.
  3. PlantUML - Software used to create UML diagrams.
  4. printScore - Method in SubjectQuiz and TopicQuiz classes which prints out the score and the incorrect answers from a quiz.

Q

  1. Quiz - An abstract class that holds the result, list of flashcards and a list of incorrectAnswers for the SubjectQuiz class and the TopicQuiz class to inherit from.
  2. quizcard - Package which contains the Quiz,Result,SubjectQuiz,TopicQuiz classes.
  3. QuizSubjectCommand - A command in the subjectcommand package which initiates a quiz for a subject.
  4. QuizTopicCommand - A command in the topiccommand package which initiates a quiz for a topic.

R

  1. RepeatedFlashcardException - An exception thrown if the user tries to add a flashcard which already exists.
  2. RepeatedSubjectException - An exception thrown if the user adds a subect which is already present in the application.
  3. RepeatedTopicException - An exception thrown if the users adds a topic that is already present in the application.
  4. repo - The repository in Github which holds the revisED project.
  5. Result - A class in the quizcard package which stores the marks from a quiz and a description which indicates the performance of the user for that quiz.
  6. result - An object of the Result class.
  7. ResultList - A class in the list package which holds an ArrayList of Results.
  8. ResultSubjectCommand - A command in the subjectcommand package which shows all the results of subjectQuizzes obtained for the subject.
  9. Revised - The main class which initiates the whole application.It is also the name of the application.

S

  1. saveTasks- Method in the Storage class which saves the tasks.
  2. saveToJson - Method in the Storage class which saves information in JSON format.
  3. saveTopics - Method in Storage class which saves the topics in the application.
  4. score - A variable in the Result class which tracks the score during the quiz.
  5. setupQuiz - Method in SubjectQuiz and TopicQuiz class which sets up the quiz by transfering the flashcards.
  6. Subject - A class which instantiates the subject object. Holds the title of the subject and lists of flashcards, results and topics.
  7. SubjectCommand - An abstract class that is inherited by all the other SubjectCommand classes in the subjectcommand package.
  8. subjectcommand - A package which holds the different Subjectcommand classes.
  9. subjectexception - A package which holds the exceptions thrown in the main level.
  10. SubjectList - A class in the list package which holds an ArrayList of Subjects.
  11. SubjectParser - A class in the parser package which reads the user commands to call the relevant Subject command.
  12. SubjectQuiz - A class in quizcard package which initiates a quiz for the subject.
  13. SorryFlashcardCommand - A command in the flashcardcommand package which highlights invalid commands in the topic level.
  14. SorrySubjectCommand - A command in the subjectcommand package which highlights invalid commands in the main level.
  15. SorryTaskCommand - A command in the taskcommand package which highlights invalid commands in the subject level.
  16. SorryTopicCommand - A command in the topiccommand package which highlights invalid commands in the subject level.
  17. Storage - A class which is saves the data when the user exits the application and loads the data once the user starts the application.
  18. storage - A package which holds the Storage class, which is in charge of storing and loading data into the application.
  19. StorageBuilder - Inner class of storage class and creates storage instances.
  20. storageexception - A package which holds the DataLoadingException.

T

  1. Task - An abstract class in the taskcard package which Todo, Deadline and Event classes inherit from.
  2. task - A package which contains the TaskList class.
  3. taskcard - Package which contains the task classes.
  4. TaskCommand - A class in the taskcommand package that is inherited by all the other TaskCommand classes in the taskCommand package.
  5. taskcommand - A package which holds the different taskcommand classes.
  6. TaskDeadlineException - An exception thrown if an invalid deadline task is added to the applcation.
  7. TaskEventException - An exception thrown if an invalid event task is added to the application.
  8. taskexception - A package which holds the exceptions related to task operations.
  9. TaskList - A class in the list package which holds the list of classes.
  10. TaskList - A class in the list package which holds an ArrayList of Tasks.
  11. TaskParser - A class in the parser package which reads the user commands to call the relevant task command.
  12. TaskTodoException - An exception thrown if an invalid todo task is added to the application.
  13. Todo - A class in the taskcard package which refers to a task without deadline.Inherits from the Task class.
  14. Topic - A class in the card package which is instantiated when the user creates the topic. Holds the title of the topic, an arraylist of flashcards and an arraylist of results.
  15. TopicCommand - An abstract class in the topiccommand package that is inherited by all the other TopicCommand classes in the topiccommand package.
  16. topiccommand - A package which holds the different topiccommand classes.
  17. topicexception - A package which holds the exceptions that are related to topic operations.
  18. TopicList - A class in the list package which holds an ArrayList of Topics.
  19. TopicParser - A class in the parser package which reads the user commands to call the relevant topic command.
  20. TopicQuiz - A class in the quizcard package which initiates the quiz for a topic.
  21. toString - A method provided by Java to convert the current object into a String. This method has been overriden in classes such as Event,Deadline to provide the accurate output .

U

  1. Ui - A class which takes care of interaction with the users. Prints the correct output to the console.
  2. ui - Package which contains the Ui class, in charge of user interactions.
  3. updateResult - Method in Result class which updates the score of a quiz.

Appendix E: Instructions for Manual Testing

Given below are the instructions to test the app manually.

📝️️ NOTE: These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.

Launching

  1. Refer to the Quick Start to download and launch the application.
  2. Expected: The application should show the greeting screen as illustrated in the quick start section.

Testing features

  1. Run each command as demonstrated in the example of usage in the Features section of the user guide.
  2. Expected: The output should match the sample output given.

Shutdown

  1. Run exit command until you reach the main level of the application (or until an error message saying the command is not recognized is displayed).
  2. Run bye command.
  3. Expected: A bye message should be displayed and the application should exit.

Saving data

When shutdown normally

  1. Create a new folder and copy the jar file used in the above steps to the new folder.
  2. Navigate to the new folder and launch the application.
  3. Run add CS2113T then subject CS2113T.
  4. Run add Java.
  5. Run exit then bye.
  6. Expected: A data/ folder containing the same structure as mentioned here should be created in the new folder.

When shutdown abruptly

  1. Follow steps 1 to 4 above to add data.
  2. Close the console running the application, then navigate to the new folder via file explorer.
  3. Expected: No folder is found created in the new folder.

Loading data

When data is not modified externally

  1. Follow all the steps above to create saved data.
  2. Launch the application again.
  3. Expected: CS2113T subject and Java topic persist in the application.

When data is modified externally

  1. Follow all the steps above to create saved data.
  2. Go into the data/ folder in the new folder.
  3. Rename the CS2113T/ folder to CS2040/.
  4. Go back to the new folder and launch the application.
  5. Expected: CS2113T subject is changed to CS2040, and Java topic remains the same in the application.