iGraduate Developer Guide

Project by: W09-2 Latest update: 12 April 2021

logo

Table of Contents

  1. Introduction
  2. Developer Guide Usage
  3. Setting up, Getting Started
  4. Design
  5. Implementation
  6. Logging
  7. Documentation
  8. Appendix A: Product Scope
  9. Appendix B: User Stories
  10. Appendix C: Non-Functional Requires
  11. Appendix D: Glossary
  12. Appendix E: Instructions for Manual Testing

Introduction

iGraduate is a Command Line Interface (CLI) application that helps NUS Information Security students track and plan their graduation by allowing them to add, delete, update modules to the module list. The users are allowed to add Core, General Education (GE), Math and Elective modules for tracking. There is also a built-in CAP calculator and Progress Command to check their graduation progress. Users can also list down modules on the list. When listing the modules, the module type will be shown accordingly.

Back to Top


Developer Guide Usage

This developer guide is made for developers who wish to further understand and/or develop iGraduate. This guide includes the setup instructions, design, implementation, logging, testing, product scope, and other sections to give developers a better understanding of the application.


The following symbols and formatting are used in this guide:

Symbols/Formatting Description
ℹ️ Note: Information to take note of.
📝 Tip: Optional information that may be useful.
⚠️ Warning! Important information that may resolve problems.
Grey highlight Code or terms related to the application.

Back to Top


Setting Up, Getting Started

This section guides you through the process of setting up the project on your computer.

ℹ️ Note: This application is developed for users with Java 11 installed on their computer. If you do not have it installed on your computer or if you have other versions of Java, follow this link to download and install it before continuing with this section.

📝 Tip: To check if you have Java 11 installed, type java --version into a command prompt

Fork the iGraduate repository to your GitHub account and clone it to your local computer. Alternatively, you could also download the source code of the application directly from our latest release.

Terminal

  1. Open a new terminal in the folder/directory where the build.gradle resides, and run gradlew.bat run on Windows platform or run ./gradlew run on macOS/Linux platform.
  2. You will see the following output in the console when the setup is successful:
Starting without existing module data...
Initializing new module list...
--------------------------------------------------------------------------------------
 _  ____               _             _
(_)/ ___|_ __ __ _  __| |_   _  __ _| |_ ___
| | |  _| '__/ _` |/ _` | | | |/ _` | __/ _ \
| | |_| | | | (_| | (_| | |_| | (_| | ||  __/
|_|\____|_|  \__,_|\__,_|\__,_|\__,_|\__\___|
iGraduate starting up...
Welcome to iGraduate, your one stop study planning service!
What would you like to do today?
--------------------------------------------------------------------------------------

IntelliJ IDEA

  1. Configure IntelliJ IDEA to use JDK 11 by referring to the IDEA set up guide.

    ℹ️ Note: This developer guide uses IntelliJ IDEA as the default IDE. It is recommended to install IntelliJ to follow the guide.

  2. Import the project as a Gradle project

    ⚠️ Warning! Importing a Gradle project is slightly different from importing a normal Java project.

    📝 Tip: IntelliJ IDEA has the Gradle plugin installed by default. If you have disabled it, go to FileSettingsPlugins to re-enable them. If there is a build.gradle file in the project root, IntelliJ treats it as a Gradle project by default.

    1. Open IntelliJ (if you are not in the welcome screen, click FileClose Project to close the existing project first)
    2. Open the project into IntelliJ
      • Click Open.
      • Select the project directory, and click OK.
      • If there are any further prompts, accept the defaults.
    3. Click OK to accept the default settings but do ensure that the selected version of Gradle JVM matches the JDK being used for the project.
    4. Wait for the importing process to finish (could take a few minutes).
  3. Verify the setup by running seedu.igraduate.IGraduate. If successful, the console would output the following:
     Starting without existing module data...
     Initializing new module list...
     --------------------------------------------------------------------------------------
      _  ____               _             _
     (_)/ ___|_ __ __ _  __| |_   _  __ _| |_ ___
     | | |  _| '__/ _` |/ _` | | | |/ _` | __/ _ \
     | | |_| | | | (_| | (_| | |_| | (_| | ||  __/
     |_|\____|_|  \__,_|\__,_|\__,_|\__,_|\__\___|
     iGraduate starting up...
     Welcome to iGraduate, your one stop study planning service!
     What would you like to do today?
     --------------------------------------------------------------------------------------
    

Back to Top


Design

The following section is an overview of the design architecture. Each Sub-section provides a more detailed explanation for the design of each individual components.

Architecture Diagram

archi

Figure 1.1.1 Architecture diagram showing an overview of the main components in iGraduate

Architecture

iGraduate has one class called iGraduate which contains a main and run method and iGraduate constructor. It is responsible for:

Commons represents a collection of classes used by multiple other components.

The rest of the App consists of four components:

  1. UI -> The UI of the App.
  2. Logic -> The command executor.
    • Parser -> Understands and interprets the commands input by user, passes command to run to Command.
    • Command -> Executes command based on what is parsed.
  3. Model -> The user data held by the program
    • Module -> Holds the information of individual modules.
    • ModuleList -> Holds data of all modules of the app in memory.
  4. Storage -> Reads data from, and writes data to, the hard disk.

Each of the four components,

Given below is the sequence diagram of the startup sequence of iGraduate before any user input.

archi

Figure 1.1.2 Sequence diagram of iGraduate from startup until before first user input.

The startup sequence sets up all objects required for running commands, such as the Ui and fetching of stored data from Storage. Given below is the sequence diagram of how the architecture handles the flow of execution of commands and how the program exits.

archi

Figure 1.1.3 Sequence diagram of iGraduate from receiving the first user input until exit.

Back to Top


UI Component

The UI is a public class that consists of three components: Scanner, Constants and Print Methods. The UI component mainly manages the retrieval of user command and display of user feedback, ranging from successful execution, execution results and exceptions.

Behaviour

archi

Figure 1.2 UML class diagram for Ui class

Back to Top


Logic Component

The logic component consists of the class Parser and the package Command. The classes work together to interpret user input, identify the right command to execute and the execution of the input command.

Behaviour


Parser Class

The Parser class is part of the logic component.

The Parser interprets user input and subsequently passes the properly processed user input to Command to execute the command.

Given below is the Parser class diagram showing the important methods that returns a Command object. As shown, Parser contains one class, Parser.java and the main function is the parseCommand() method.

archi

Figure 1.3 UML class diagram for Parser class

Behaviour

ℹ️ Note:

The methods that extract the various parameters and flags, which would be invoked based on the command word detected in the user input:

Method Description Invoked with
extractModuleCode() Extracts the module code by checking for the -c flag. createAddCommand()
extractModuleType() Extracts the module type by checking for the -t flag. createAddCommand()
extractModuleCredits() Extracts the module credits by checking for the -mc flag. createAddCommand(), createUpdateCommand()
extractModuleGrade() Extracts the module grade obtained by checking for the -g flag. createDoneCommand(), createUpdateCommand()
extractModuleName() Extracts the module name by checking for the -n flag. createUpdateCommand()
extractPreRequisites() Extracts the module prerequisites by checking for the -p flag. createAddCommand(), createUpdateCommand()
extractListScope() Extracts the list type. Accepts all, complete, incomplete or available as acceptable scopes. createListCommand()

Table 1.4 Methods invoked to extract various flags in various commands


The method that check various parameters:

Method Description
isModuleCodeValid() Checks that the module code is a valid module code according to the standard for NUS modules. The method uses regex to check for the valid code. There are 2 overloading methods - one for checking a single instance and another for an array list to check through a list of module codes.

Table 1.5 Method invoked to check the validity of the module code inputted


Command Package

The command component executes the correct command based on what the parser interprets.

The command component consists of an abstract class Command and 10 subclasses that inherit from it. The subclasses are:

  1. AddCommand
  2. CapCommand
  3. DeleteCommand
  4. DoneCommand
  5. ExitCommand
  6. HelpCommand
  7. InfoCommand
  8. ListCommand
  9. ProgressCommand
  10. UpdateCommand

Behaviour
The correct command is executed once the Command object is created by the parser by executing the execute() method in the correct subclass. The command execution can affect the Model (e.g. adding a module). At the end of each command execution, different methods in the Ui will be called to perform certain actions, such as displaying the list of modules to the user.

Below are the Command class diagrams, split into 3 diagrams for better readability.

archi

Figure 1.6.1 UML class diagram for Command class part 1

archi

Figure 1.6.2 UML class diagram for Command class part 2

archi

Figure 1.6.3 UML class diagram for Command class part 3

Back to Top


Model Component

The model component consists of two main packages, module and list, which define and deal with data storing issues based on the information provided by the user input.

Behaviour
The data storing issues are split into two main categories - what data should be included in a module and a container managing the module objects.


Module Package

The module package consists of classes that are used to define the type of data to be stored in a module object and establish a framework to show how other components can make use of the features in module classes.

Behaviour
The module package consists of classes related to module objects.

A class diagram illustrating the relationship between the interaction of classes under the module package is shown below.

archi

Figure 1.7 UML class diagram for the Module package

The following child classes handle different types of modules based on the generic module type available in the university:

Each of the module classes consists of:


Module Class

Module class is an abstract class in the module package. It holds the attributes and methods for manipulating the attributes applicable to all modules. The attributes found in the Module class are relevant to NUS module information.

Behaviour

The Module class also consists of methods that set and get the value of attributes shown in the table above. There are four additional methods in the class, namely removeUntakenPreRequisite, removeRequiredByModule, getStatusIconand toString . The removeUntakenPreRequisite and removeRequiredByModule methods are used to remove a singleuntakenPreRequisites module and requiredByModules module respectively, whereas getStatusIcon returns the status icon based on the module status. For customized formatting of module printing messages, toString method is overridden.

Child Class Behaviour
CoreModule Initializes the core module object with the information needed and contains a toString method that overrides the format of core module printing.
GeModule Initializes the general education module object with the information needed and contains a toString method that overrides the format of general education module printing.
ElectiveModule Initializes the elective module object with the information needed and contains a toString method that overrides the format of elective module printing.
MathModule Initializes the math module object with the information needed and contains a toString method that overrides the format of math module printing.

Table 1.8 Child classes that inherited from the Module class


List Package

The list package contains an ArrayList of type Module, representing the entire list of Module objects added by the user. It also defines the methods used to modify the data of existing Module objects, such as adding, deleting or marking a Module as done.

Behaviour
The package consists of 1 class, ModuleList.java. ModuleList contains 2 constructor signatures; 1 for constructing a new, empty list for when the user uses iGraduate for the first time, and the other to contain the modules already stored in Storage.


ModuleList Class

The ModuleList class acts as an abstraction for the ArrayList that is used to store module objects created from any of the classes under the module package.

Given below is the class diagram of ModuleList showing its 3 main functions.

archi

Figure 1.9 UML class diagram for ModuleList class

Behaviour
The ModuleList class:


Add a Module

The methods add, addModuleRequiredBy and removeTakenByPrerequisites are invoked to add a module.

The following shows the process of adding a module named newModule:

  1. addModuleRequiredByis called to populate the list of modules that require newModule as a prerequisite.
  2. removeTakenByPrerequisites checks the list of prerequisites of newModule and removes the ones that have been marked as taken.
  3. add calls ArrayList.add() to add newModule to the list.

Delete a Module

The methods delete and removeFromPreRequisiteModuleRequiredBy are invoked to delete a module.

The following shows the process of deleting a module named existingModule:

  1. delete calls ArrayList.remove() to delete existingModule from the list.
  2. removeFromPreRequisiteModuleRequiredBy is called to remove existingModule from its pre-requisite modules’ requiredBy list.

Mark Module as Taken

The methods markAsTaken and removeFromModuleUntakenPrerequisites are invoked to mark a module as taken.

The following shows the process of marking a module named existingModule as done:

  1. markAsTaken calls Module.setStatus and sets the status of existingModule to “taken”.
  2. removeFromModuleUntakenPrerequisites is called to remove existingModule from the prerequisitesUntaken table from the list of modules that require existingModule as a prerequisite.

Back to Top


Storage Component

The storage component consists of the class Storage. The storage component is closely associated with the ModuleList component to store latest module information (including completion, code, name, prerequisites, etc.) in a JSON format after every manipulation of ModuleList. This includes adding, deleting and updating of modules, as well as marking a module as done.

Class Diagram:

archi

Figure 1.10 UML class diagram for Storage package

Behaviour
The Storage Component,

archi

Figure 1.11 UML object diagram for an instance of storage object

Back to Top


Common Classes

The common class used by multiple components in this app are in the exception package. The exceptions are thrown when an error occurs. The method catches the exceptions and prints out the respective error message.

ℹ️ Note: Each exception is specified by the name and description.

Behaviour

This section elaborates on some details about how certain features are implemented.

Back to Top


Implementation

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

UI

The Ui feature has 3 primary responsibilities:

  1. Executes user command using Logic Component
  2. Prints resulting message
  3. Listens to calls from Model data

Back to Top


Parser

The parser feature has 4 primary responsibilities:

  1. Identify the command the user wants to run
  2. Extract the relevant parameters and flags required to run the command
  3. Check the validity of the parameters and flags
  4. Create a new Command object and hand it over to iGraduate to execute


archi

Figure 1.12 Sequence diagram of Parser in execution with done CS1010 -g A as user input

Details
There are 3 classifications of user input: command, parameter and flags.

User input Description Usage/Example
command the type of command the user intends to run and is first word from the user input dictates how Parser extracts the parameter and flags. Refer to Command for the list of available commands
parameter the argument that comes after the command word and can vary depending on the command specifies the identifier (module name or code or list type) for the modules. For example, the parameter for addcommand would be the module name, but the parameter for delete would be the module code. For list, the parameters would specify the type of list (complete, incomplete or available)
flag comes after parameters and are available only for a few commands specify the additional information required for the command to run. For add, flags would be for module code, module type, MCs and prerequisites.

Table 1.13 Terms used in differentiating the different parts of a user command

Considerations : How to implement parsing of user input

From the start, it was known that Parser would be one of the more challenging components to implement due to the large number of commands and the variance in parameter and flag types. Another difficult problem to navigate around was the validation of the format and values of the parameters and flags. Initially, no validation checks were implemented in Parser, with the respective Command subclasses doing the input validation for their specific parameters and flags. However, the Storage component also requires the same checks as the Command component. As such, there was a dependency between Storage and Command, which does not make sense as the responsibilities of the two are completely unlinked. Hence, the validation of parameters and flags were moved to Parser. In this implementation of Parser, the Storage and Command components are unaware of each other, instead relying on Parser for extracting and validating inputs. This helps to eliminate the dependency between Storage and Command.

Alternatives

  1. Custom (current choice): Designing and implementing a custom parser for iGraduate
    • Pros:
      • Better suited for target users (fast typists)
    • Cons:
      • Less sophisticated error and exception handling
      • Higher risk of bugs
      • More complicated to implement
  2. Outsource: Adopt third-party libraries to perform parsing
    • Pros:
      • More resilient to error and exceptions
      • Less design considerations
    • Cons:
      • Less suitable for iGraduate behaviour

Considerations were made for the adoption of third-party parser libraries. However, the third-party libraries obtained did not achieve the behaviour that was envisioned. Instead of keeping the application running when executing any commands, the command, parameters and flags would have to be directly piped in the command terminal, together with the application. This would create an instance of the iGraduate application before terminating after one command. Though this may provide a far superior parsing and error and exception handling, the behaviour does not support the target audience. Therefore, the decision was made against using a third-party library. Instead, attempts were made to mimic the behaviours and error handling of the libraries, but within the context of the running application.

Considerations : Format to store module information

An arrayList is used to store the parsed data from the user input instead of an array. This is to make use of the built-in class functions (especially indexOf() and size()). The array class also lacks certain features that are of good use to the parser class. This includes the use of regex for checking against the values stored in each index without making the process too manual. For instance, matches() of arrayList automatically takes in a regex instead of having to manually create a regex object, then parsing into the find() function, which loops through the entire array to obtain the matches. This significantly simplifies the code in the parser function, and makes handling exceptions easier.

Alternatives

  1. ArrayList (current choice)
    • Pros:
      • Equipped with useful built-in class functions
      • Significantly simplifies logic needed to parse flags and parameters
    • Cons:
      • Less Memory efficient
  2. Array
    • Pros:
      • Efficient memory allocation
      • Fixed size, which uses less memory
    • Cons:
      • Inefficient in extracting input flags
      • Limited functionalities

Initially, it was decided that the parameters would be split into an array to utilise the efficient memory allocation and standard size because arrays are more memory efficient. The parsing does not modify any values in the array after the initial split to the arrays (i.e. no additions of removal of data needed). However, the process needed to extract the flags from the array is inefficient, and requires another method to locate. Furthermore, the array in limited in its capabilities, making the coding of some behaviour complicated (such as filtering with a regex value). Therefore, the array ultimately got changed into an arrayList type, since arrayList has more features that can be utilised to make the code more efficient.

Back to Top


Command

The command package is responsible for executing the command from the user. The package contains the abstract class Command and 10 subclasses that inherit Command, one for each valid iGraduate command .

Details
The abstract class Command contains only 1 method: execute(), which takes in 3 parameters: moduleList, ui and storage. These 3 parameters aid with printing information to the user, making modifications to the data and saving the data. Each subclass of Command overrides execute() and implements their own methods to execute the command. Each subclass also has a unique constructor signature as each subclass requires different parameters to execute.

Implementation
The implementation for executing every command differs, and the implementation details of each of them will be further elaborated below.


Add Command

The add command allows a user to add a new module to the list of existing modules. The module name is part of the parameters and is extracted directly from user input while the various information required to add a new module are included in the flags of the user input.

There are 3 compulsory flags and 1 optional flag for adding a module:

  1. module code
    • -c <String>
  2. module credits
    • -mc <double>
  3. module type
    • -t <String>
  4. (Optional) prerequisite modules
    • -p [<String>, ...]

ℹ️ Note: The order of flags in user input does not matter.

The sequence diagram below shows the execution of add command in action:

archi

Figure 1.14 Sequence diagram of AddCommand in execution with add Programming Methodology -c CS1010 -mc 4 -t core as user input.


Delete Command

The delete command allows for deletion of module from the module list, identified by the module code, which is extracted from user input as a parameter. There are no flags involved for deleting a module.

ℹ️ Note: Users cannot delete modules which are prerequisites for other modules.

archi

Figure 1.15 Sequence diagram of DeleteCommand in execution with delete CS1010 as user input


Update Command

The update commands allows users to modify existing modules, identified by the module code. The information that can be updated include module name, credits, prerequisites and grades (if the module is marked as done).

The module code is extracted from user input as a parameter while the various information requested to update would be identified with their flags:

ℹ️ Note:

archi

Figure 1.17 Sequence diagram of UpdateCommand in execution with update CS1010 -mc 2 as user input

Considerations : Command behaviour

The main considerations regarding the behaviour of the update command would be if multiple flags should be permitted in a single update command.

Alternatives

  1. Restrict to single update flag
    • Pros:
      • Simple to implement
      • Easier error and exception handling
    • Cons:
      • Inconvenient and unsuitable for target audience
  2. Allow multiple flags (current choice)
    • Pros:
      • Suitable for target audience who are fast typists
      • Update Command makes it more convenient for users to change module information as compared to deleting a module and adding it again.
    • Cons:
      • Complicated process when extracting flags
      • More considerations needed for error and exception handling

Having a single input would significantly simplify the code, as a simple switch statement will suffice. There is also less error and exception handling as only two parameters are given. In the event of an exception, simply retrace the command and throw exception. However, having only one flag at a time is inconvenient for fast typists, and is less optimized for their quick typing.

Another alternative was to allow multiple flags, each with their own input and error handling. Extraction would be significantly more complex, as each flag has to be accounted for, extracted together with its trailing new value. Should one of the flag cause an exception, another consideration would be to determine if the command should be completely aborted or just the failed flag. The greatest advantage of parsing multiple updating instances would be to allow fast typists to quickly make multiple changes in a single command line. This caters much more to the target audience, and makes using iGraduate more convenient. Ultimately, decision was made to allow multiple flags, individually parsed with their own checks and extraction methods, reused from the other commands.

Considerations : Command error and exception handling management

On the event of a failed flag, considerations have to made to determine how the update command would manage the rest of the flags.

Alternatives

  1. Abort entire command
    • Pros:
      • Simple to implement
    • Cons:
      • Major inconvenience to users
  2. Ignore failed flag
    • Pros:
      • More usable and convenient for users
    • Cons:
      • Extremely complex in error and exception handling
  3. Ignore failed grade flag (current choice)
    • Pros:
      • Compromise between convenience and code difficulty
      • If grade flag generates an error, the other flags would still be updated
    • Cons:
      • Failure in other flags still results in aborting the entire command

The first way is to completely abort the entire command, which lowers the usability aspect of the application, creating inconvenience when a small error is encountered. However, this makes coding straightforward and simple.

Another alternative is to simply ignore the failed flag and attempt to change the rest. This would make the update command more usable and convenient. However, the primary issue is the difficulty in designing and programming such behaviour, individual try and catch statements needs to be used. Each statement must be able to differentiate between having an invalid flag input or having a flag that does not exist (i.e. the user did not use the flag). This behaviour makes the application significantly more complex to code and catch.

Finally, decisions were made to compromise between the two alternatives. After some discussions, it was determined that grade (the -g flag) is the most likely to fail since it depends on not just the user input but if the module has been completed. Therefore, a dedicated try statement is used to ensure that, even in the event of errors associated with providing a grade to an incomplete module, the rest of the command would still be updated (the rest of the extracts and checking is in the final clause). Unfortunately, if the other flags fail, the program will abort entirely. This alternative balances the complexity between error and exception handling and usability, allowing some flexibility in managing error while providing some convenience.


Info Command

The info command provides a feature for the user to view any module they added to the list regardless of the module type and status by specifying its module code. The module code is extracted from user input as a parameter. The command will only be executed if valid module code is provided by the user. All information of the specified module will be shown to the user to aid the planning of module.

There are no flags required for this command.

An example of info command execution flow is shown in the sequence diagram below.

archi

Figure 1.18 Sequence diagram of InfoCommand in execution with info CS1010 as user input

Considerations

After receiving feedback from a user stating that there are no ways for the user to view the prerequisite information for any modules, the team considered implementing a prerequisite column for the list command as suggested by the user. However, after much consideration and discussion, the team felt that it could become too convoluted and cluttered for the list command results as there are simply too much information to show in one screen. Instead, the team decided to create a new info command to list the information of the module based on the module code as specified by the user.


List Command

The list command provides users with 8 options to list down the modules being tracked by iGraduate. The options come in the form of a parameter that is extracted from user input.

The table below is an overview of the list commands.

List Parameter Scope
all List all modules being tracked
complete List modules that have been marked as done
incomplete List modules that have not been marked as done
available List incomplete modules available to be marked as done based on prerequisites completed
core List all core modules on the list
math List all math modules on the list
elec List all elective modules on the list
ge List all GE modules on the list

Table 1.19.1 Overview of the List function

list

Figure 1.19.2 Sequence diagram of ListCommand in execution with list complete as user input


CAP Command

The CAP command calculates the current CAP of the user based on the grades of modules that are marked as done. The command also displays the degree classification of the user. There are no flags or additional parameters required.

archi

Figure 1.20 Sequence diagram of CapCommand class.


Done Command

The done command is used to mark a module as completed. To execute this command, the module code is extracted as a parameter from user input, and there is 1 compulsory flag:

  1. Grade obtained for module
    • -g <String>

ℹ️ Note: Only the following letter grades (A+, A, A-, B+, B, B-, C+, C, D+, D, F, S, U, CS, CU) are valid.

ℹ️ Note: Module codes are case-insensitive. This means that module codes like CS2102 and cs2102 are considered the same.

archi

Figure 1.21 Sequence diagram of DoneCommand in execution with done CS1010 -g A as user input


Progress Command

The progress command prints a progress bar as well as the user’s graduation progress in the form of a percentage. No additional flags are required for this command.

archi

Figure 1.22 Sequence diagram of ProgressCommand in execution.


Help Command

The help command provides users with a quick reference guide to the list of available commands, their functions and the proper format for inputs. Users also have an optional parameter to find the reference guide for a specific command.

The optional parameters are:

ℹ️ Note: If no parameters are provided, a brief description of the program and the available commands will be printed instead.

The figure below demonstrates the behaviour of the help command.

archi

Figure 1.23 Sequence diagram of HelpCommand in execution with help add as user input.

Considerations

A quick reference guide where users can see the summary of commands and the different formats for each command. One implementation considered was the format used for Linux man pages, where a single command line input displays all information about the functionality of the command and the types of parameters accepted. This was the most straightforward implementation due to the ease of parsing possible user inputs and there being only one kind of message to be displayed. This proved to be unfeasible from a User Experience point of view as there was too much information displayed at one go due to the number of commands the application has and their unique formats. Instead, the team opted to go for a more segmented implementation of the help command, with one command showing users how to use the reference guide while the other commands provide a readable reference guide to the user that targets the command that users want to know more about.

Back to Top


Module

The module component contains the class module, together with 4 child classes that inherit from module. All modules stored in iGraduate are instances of one of the 4 subclasses.

Details

For the implementation of modules in iGraduate, most of the information used to identify a module are contained in the parent class module. The class contains the setters and getters of all the data pertaining a module, such as the module code, grade and MCs. It also contains the lists that track the prerequisites of the module.

The implementation details of the subclasses are hence quite sparse, containing only a constructor and a public method toString() which identifies the type of module stored in the module object.

Considerations

To accommodate the wide range of operations available to the modules, the implementation of the module component had to be comprehensive in the data it stores. However, since every module shares the same categories of data to store, such as module code and grade, the subclasses do not contain much information that is not already stored in their parent class. To better accommodate our list by module type feature, the subclass each module belongs to is determined by the module type.

Back to Top


ModuleList

The moduleList component acts as a temporary storage for storing module data while application is running. All module data added to the application could be found under the moduleList storage.

Details

Since the moduleList is used for storing module data needed for running application, the module data will be loaded from the disk when the application first started. After any data changing command is executed, the latest module data in the moduleList will be written to disk for permanent storage (unless the secondary memory is faulty). It also consists of utility methods which allows retrieval, manipulation and deletion of module data in a centralised and consistent manner.

Considerations

At the start of project, an array is considered to be used as the underlying data structure for the moduleList component. However, after taking the scalability issue into consideration, the team decided to incorporate an ArrayList instead. Reason being ArrayList is a dynamically sized array along with standard methods such as whether the list contains a specific module, search and removal of specified module. The size of the ArrayList is only limited by the user device’s available memory size.

Back to Top


Storage

The storage feature saves the state of the module list after every execution of commands that manipulates (i.e. update, add or delete) the modules in the list.

Details

The storage function is executed after every command that manipulates (i.e. adds, deletes or updates) the modules in the module list, saving the updated state into the storage file.

The module list is stored in a storage file named modules.json in the data folder (<program location>/data/modules.json).

The figure below demonstrates the behaviour of the storage feature.

archi

Figure 1.23 UML sequence diagram showing the life of Storage when the Add command is invoked

Considerations

The main reason in using a JSON file instead of designing one is to allow a more robust error and exception handling and management with respect to modified storage files. The parsing of JSON format is also more sophisticated and reliable.

In addition, the JSON format can be read across multiple different types of applications, allowing flexibility in any future implementations regarding exporting of data.

Alternatives

The alternative storage format considered is the use of delimiters. However, there are concerns regarding such usage; the most important being potential parsing failure from a valid module. With the use of common delimiters such as commas , and dashes -, the program is unable to differentiate between the various module information and legitimate module names containing delimiters and may parse the portion of the module to a wrong variable, resulting in a corrupted program. One example of such occurrence would be a module named Software Engineering and Object-Oriented Programming, which contains dashes when the delimiters are used for separating various module information is also a dash.

Considerations were also given to use more unique delimiters (such as \, |, etc.) to avoid accidental parsing failures, but the problem still remained. Attempting to fuzz characters would lead to a corrupted storage file and render the application useless. Ultimately, the idea was scrapped in favour of the JSON format with a third-party library, since the exception handling and parsing management lies in the library functions.

Back to Top


Exception

Exception is an event that disrupts the normal flow of the diagram. It is an object that is thrown at runtime. In iGraduate, there are several exceptions that are thrown due to different conditions.

Exception Description
AddSelfToPrereqException This exception is thrown when user updates a module’s list of prerequisites to include the module itself.
DataFileNotFoundException The exception is thrown if module data file is not found.
ExistingModuleException The exception is thrown if the module code input already exists.
IllegalParametersException The exception is thrown if the parameter includes any parameters not allowed in the command.
IncorrectParameterCountException The exception is thrown if the parameters given is incorrect.
InputNotNumberException The exception is thrown if input is not an integer.
InvalidCommandException The exception is thrown if the command input was invalid.
InvalidListTypeException Exception is thrown if list command is not followed by: all, incomplete and complete.
InvalidModularCreditException Exception is thrown if modular credit input is negative.
InvalidModuleGradeException The exception is thrown if module grade input is invalid.
InvalidModuleTypeException The exception is thrown if the module type input is invalid.
LoadModuleFailException The exception is thrown if module cannot be loaded properly.
MarkCompletedModuleException The exception is thrown if module is already marked completed.
ModifiedStoragefileException The exception is thrown if the json file has been modified (when credits > 32 or credits < 0).
ModuleNotCompleteException The exception is thrown if the module being updated (on grade) has not been completed.
ModuleNotFoundException The exception is thrown if the module cannot be matched.
PrerequisiteNotFoundException The exception is thrown if the pre-requisite module cannot be matched.
PrerequisiteNotMetException Exception is thrown if prerequisite of the module has not been completed.
SaveModuleFailException This exception is thrown if the program fails to save data to file.
UnableToDeletePrereqModuleException This exception is thrown when user tries to delete a pre-requisite module.

Table 1.24 The Summary list of all exceptions used in iGraduate

Back to Top


Logging

The logging feature is implemented using the java.util.logging package. It is a default logging package included in the Java package. To learn more about the package, you may refer to here. To make use of logging feature, you will need to include the following line at the start of all the classes where logging feature is to be used.

private static final Logger LOGGER = Logger.getLogger(ClassName.class.getName());

When including the line above, remember to replace ClassName with the name of current class such as iGraduate. Once you have done instantiating the logger object with the code above, you can use the logger object to start logging. For more information on how logging works, refer to the official documentation. The logging configurations are specified in the logger.properties file located in src/main/resources/logger.properties. To change the logging configurations, simply modify the logger.properties file with the respective value. The current configuration logs all messages with level of FINE and above into a log file, iGraduate-0.log, under the same folder where the application resides.

Back to Top


Documentation

All the documentations related to the application are stored under the /docs folder. There are currently three documentations, AboutUs.md, UserGuide.md and DeveloperGuide.md. The documentation tools used for developing these guides are:

Back to Top


Appendix A: Product Scope

Target User Profile

Value Proposition

Allows users to manage modules faster than a typical mouse/GUI driven app.iGraduate Includes higher level features such as ability to add modules while ensuring user has cleared all prerequisites and to list all modules taken, graduation progress and current CAP with degree classification.

This app will help NUS students majoring in Information Security check his/her graduation progress and modules taken in a coherent manner based on the program requirements. It also contains tools as mentioned above to help students make informed decisions about future modules to take.

Back to Top


Appendix B: User Stories

Version As a … I want to … So that I can …
v1.0 user see the list of modules I can take now decide on which modules to register
v1.0 user clearly see which modules I have taken to check my prerequisites
v1.0 user delete mods that I have added amend any typos
v1.0 user add new modules that I have taken track the modules I have taken
v1.0 user utilise the CLI to input my information and execute functions  
v1.0 user have my data be persistent access it again next time when I run the program
v1.0 impatient user access information quickly  
v1.0 lazy user access information with as little effort as possible  
v1.0 user know my academic progress estimate my pace and plan for the future
v2.0 careless user know if the module I entered is valid  
v2.0 user calculate my current CAP  
v2.0 user know if the module I entered is valid monitor my performance throughout the course of study
v2.0 user see what modules I have already taken plan what modules to take next semester
v2.0 forgetful user know if I meet the prerequisites for computing modules I want to take  
v2.0 user edit the modules for the course amend my mistakes or changes in module details
v2.0 user be able to pick out any module as my UE  
v2.0 user know the pre-requisites of a module plan my semesters better
v2.0 user see all core modules I have to take  
v2.0 user be able to choose any electives of my course  

Table 1.25 All user stories considered in the designing of iGraduate

Back to Top


Appendix C: Non-Functional Requirements

  1. Should work on any mainstream OS as long as it has Java 11 or above installed.
  2. Should be able to hold up to 1000 modules without a noticeable sluggishness in performance for typical usage.
  3. A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
  4. A user without online connection should still be able to use the application.
  5. A user should be someone studying in National University of Singapore.
  6. A beginner user without prior knowledge should be able to pick up the application comfortably.

Back to Top


Appendix D: Glossary

Term Definition Usage/Example
command the type of command the user intends to run and is first word from the user input; dictates how Parser extracts the parameter and flags. Refer to Command for the list of available commands
parameter specifies the identifier (module name or code or list type) for the modules. For example, the parameter for add command would be the module name, but the parameter for delete would be the module code. For list, the parameters would specifies the type of list (complete, incomplete or available)
flag comes after parameters and are available only for a few commands; specifies the additional information required for the command to run. For add, flags would be for module code, module type, MCs and prerequisites.
delimiters a sequence of one or more characters that specifies the boundary between different streams The delimiters such as commas, and dashes are used to differentiate the parameters for parsing.
parsing the process of converting code into a more readable data format a command is parsed through the parser class to create different commands.

Table 1.26 Definitions and context of terms used in the developer guide

Back to Top


Appendix E: Instructions for Manual Testing

Given below are instructions on how 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.

Launch and Shutdown

  1. Initial launch

    • Download the jar file and copy into an empty folder

    • Run the jar file on your command prompt with the by typing “java -jar iGraduate.java” then enter.

  2. Shutdown

    • The program shutdowns automatically after entering the command exit in iGraduate.

Adding a Module

Adding a module into the module list.

Prerequisites:

Test cases:

  1. add Programming Methodology -t core -mc 4 -c CS1010
    Expected: Module added successfully.

     --------------------------------------------------------------------------------------
         Added CS1010 Programming Methodology to the list. (4.0MCs)
            
         [C][✘] CS1010   Programming Methodology                                 NIL   4 MC
     --------------------------------------------------------------------------------------
    
  2. add Programming Methodology -t core -mc 4 -c CS1010 Expected: Error in adding module as module type is invalid.

     --------------------------------------------------------------------------------------
     The module type you have entered is invalid.
     The supported module types for add are: ue, ge, core and math.
     --------------------------------------------------------------------------------------
    
  3. add Programming Methodology -t core -mc -c CS1010
    Expected: Error in adding module as there is incorrect number of parameters given, which in this case number of mc is not given.

     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect. 
     Please double check and try again.   
     --------------------------------------------------------------------------------------
    
  4. Other incorrect add commands to try: add, add nothing
    Expected: Similar to test case 3.

     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect. 
     Please double check and try again.   
     --------------------------------------------------------------------------------------
    

Deleting a Module

Deleting modules from a given module list.

Prerequisites:

Assumption:

Test Cases:

  1. delete CS1010
    Expected: Module deleted successfully.

     --------------------------------------------------------------------------------------
     "Core" module CS1010 has been deleted.
     --------------------------------------------------------------------------------------
    
  2. delete CS1020
    Expected: Error in deleting module as module is not in the list.

     --------------------------------------------------------------------------------------
     The module code you have entered does not exists. 
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  3. delete CS1010
    Expected: Error in deleting module as delete is an unknown command word.

     --------------------------------------------------------------------------------------
     The command you have entered is incorrect. 
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  4. delete -g A CS1010
    Expected: Error in deleting module as extra parameter, e.g. -g A, is found.

     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    

Marking Modules as Done

Masking modules as done with grade obtained after the semester.

Prerequisites:

Assumption:

Test Cases:

  1. done CS1010 -g A+
    Expected: Module marked as done with grade A+ successfully.
     --------------------------------------------------------------------------------------
     Nice! I've marked this module as done:
     [C][✓] CS1010   Programming Methodology                                  A+   2 MC
     --------------------------------------------------------------------------------------
    
  2. done CS1020
    Expected: Error in marking module as done as module is not in the list.
     --------------------------------------------------------------------------------------
     The module code you have entered does not exists.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  3. done CS1010 A+
    Expected: Error in marking module as done as flag -g is not found before the grade A+.
     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  4. done CS1010
    Expected: Error in marking module as done as incorrect number of parameters are given, e.g. missing grade.
     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  5. Other incorrect done commands to try: done, done -g A+
    Expected: Similar to previous.
     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    

Updating the Module List

Update the modules in module list with changes in module credits or module grade.

Prerequisites:

Assumption:

Test Cases:

  1. update CS1010 -g A- -mc 2
    Expected: Module grade and module credits updated successfully.
     --------------------------------------------------------------------------------------
     Nice! I've updated this module:
     [C][✓] CS1010   Programming Methodology                                  A-   2 MC
     --------------------------------------------------------------------------------------
    
  2. update CS1010 -g A-
    Expected: Module grade updated successfully.
     --------------------------------------------------------------------------------------
     Nice! I've updated this module:
     [C][✓] CS1010   Programming Methodology                                   A   4 MC
     --------------------------------------------------------------------------------------
    
  3. update CS1010 -mc 2
    Expected: Module credits updated successfully.
     --------------------------------------------------------------------------------------
     Nice! I've updated this module:
     [C][✓] CS1010   Programming Methodology                                   A+  2 MC
     --------------------------------------------------------------------------------------
    
  4. update
    Expected: Error in updating module as not parameters were given.
     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  5. update CS1234 -g A- -mc 2
    Expected: Error in updating module as module is not found in the module list.
     --------------------------------------------------------------------------------------
     The module code you have entered does not exists.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  6. update -g A- -mc 2
    Expected: Error in updating module as no module name is given.
     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    
  7. Other incorrect update commands to try: update, update CS1010.
    Expected: Similar to previous.
     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    

CAP

Display current CAP and degree classification of user.

Assumptions:

Test Cases

  1. cap
    Expected: CAP and degree classification displayed successfully.
     --------------------------------------------------------------------------------------
     Current CAP: 4.50
     Current Degree Classification: Honours (Highest Distinction)
     --------------------------------------------------------------------------------------
    
  2. cap gg
    Expected: Error as there is extra parameters found.
     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    

Progress

Display user’s progress towards graduation.

Assumptions:

Test Cases

  1. progress
    Expected: Progress displayed successfully.
     --------------------------------------------------------------------------------------
     Progress:
        
     ░░░░░░░░░░░ 2.50%
     4MCs/160MCs Completed
     --------------------------------------------------------------------------------------
    
  2. progress gg
    Expected: Error as there is extra parameters found.

     --------------------------------------------------------------------------------------
     The number of parameters provided is incorrect.
     Please double check and try again.
     --------------------------------------------------------------------------------------
    

List Modules

List modules in the modules list.

Assumption:

Test Cases

  1. list all
    Expected: All modules listed successfully.
     Module List:
     1: [C][O] CS1010   Programming Methodology                                   A   4 MC
     2: [C][X] CS2040C  Data Structures and Algorithms                          NIL   4 MC
    
  2. list complete
    Expected: All completed modules listed successfully.
     Modules you have have completed:
     1: [C][O] CS1010   Programming Methodology                                   A   4 MC
    
  3. list incomplete
    Expected: All incomplete modules listed successfully.
     Modules you have yet to complete:
     1: [C][X] CS2040C  Data Structures and Algorithms                          NIL   4 MC
    
  4. list
    Expected: Error in listing modules as list type not given.
     The number of parameters provided is incorrect.
     Please double check and try again.
    
  5. list all completed
    Expected: Error in listing modules as list type invalid.
     The list type you have entered is invalid.
     The supported list types for list are: all, incomplete and complete.
    

Saving Data

Dealing with missing/corrupted data files.

  1. While not in iGraduate, delete json file under /data directory. Then start iGraduate.
    Expected: iGraduate accepts current content of files as empty and functions as per normal.
     Starting without existing module data...
     Initializing new module list...
     --------------------------------------------------------------------------------------
     _  ____               _             _
     (_)/ ___|_ __ __ _  __| |_   _  __ _| |_ ___
     | | |  _| '__/ _` |/ _` | | | |/ _` | __/ _ \
     | | |_| | | | (_| | (_| | |_| | (_| | ||  __/
     |_|\____|_|  \__,_|\__,_|\__,_|\__,_|\__\___|
     iGraduate starting up...
     Welcome to iGraduate, your one stop study planning service!
     What would you like to do today?
     --------------------------------------------------------------------------------------
    
  2. While not in iGraduate, corrupt the json file under /data directory. Then start iGraduate.
    Expected: iGraduate senses the corrupted files, replace it with empty content and functions as per normal.
     Unsupported changes in storage file detected, using new storage file.
     Note: If you wish to attempt to fix the configuration, exit program immediately.
     Do not perform any commands or you will lose the original storage file.
     --------------------------------------------------------------------------------------
     _  ____               _             _
     (_)/ ___|_ __ __ _  __| |_   _  __ _| |_ ___
     | | |  _| '__/ _` |/ _` | | | |/ _` | __/ _ \
     | | |_| | | | (_| | (_| | |_| | (_| | ||  __/
     |_|\____|_|  \__,_|\__,_|\__,_|\__,_|\__\___|
     iGraduate starting up...
     Welcome to iGraduate, your one stop study planning service!
     What would you like to do today?
     --------------------------------------------------------------------------------------
    

Back to Top