1. PROJECT: One Life


1.1. Overview

This portfolio documents the features and enhancements that I have made to the project and the contributions I have made to the User and Developer guide.

One Life is a desktop medical database application used for storing and displaying data related to patients and doctors. The project was developed as part of the requirements for the CS2103T (Software Engineering) module. One Life aims to be a simplified, non-complex system that is responsive and easy to use, so as to increase efficiency in the processes of medical staff and to reduce the amount of human errors made in the medical field.

The user interacts with One Life using a Command Line Interface (CLI), and it has a Graphical User Interface (GUI) created with JavaFX. It is written in Java, and has about 10 kLoC.

1.2. Summary of contributions

  • Major enhancement: added the intuitive command prompt feature

    • What it does: intuitively guides and instructs the user to enter the correct inputs into the required fields of a command

    • Justification: This feature improves the product significantly because new or less tech-saavy users are able to easily use the product. The step-by-step walkthrough of commands by the intuitive command prompt also simplifies the typing of commands and can potentially reduce human error.

    • Highlights: This enhancement involves all commands that take in one or more arguments. The implementation of the enhancement required classes that could keep track of arguments and have different prompting behaviours depending of the type of command to be executed.

  • Minor enhancement: added command box clear ability and cancellation of intuitive command ability on ESC key press.

  • Code contributed: [Functional code] [RepoSense]

  • Other contributions:

    • Project management:

      • Managed releases v1.1 - v1.4 (4 releases) on GitHub

      • Tagged releases, compiled binary (JAR) files and published releases on GitHub

    • Documentation:

      • Updated class diagram for Model component: #144

    • Community:

      • Reviewed PRs of other team members: #54

2. Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

2.1. Intuitive command prompting

Provides a more natural way of entering commands into One Life. One Life will prompt the user for the next required input - no prefixes are required.

Commands that support intuitive prompting:

  • add

  • delete

  • edit

  • find

  • schedule

  • update

Format: COMMAND

Type /bk to re-enter previous field.
Type // if the field is to be left blank (only available for optional fields).
Press ESC to cancel the currently executing command.

Examples:

  • add
    Starts an intuitive add command. This triggers the intuitive command prompt, and One Life will begin to guide you through the command with instructions, as shown in the figure below:

StartIntuitiveCommand
Figure 1. Starting the intuitive add command
  • patient
    Specifies that a patient is to be added to the intuitive command prompt. The intuitive command prompt then asks for the next input, in this case the patient’s name, as shown in the figure below:

NextIntuitiveInput
Figure 2. Entering an input
  • /bk
    Goes back to the previous field. A new input can be reentered for this field, as shown in the figure below:

BackIntuitive
Figure 3. Going back to the previous field
  • ESC
    Cancels the intuitive command. This clears the command box and exits the intuitive command, allowing for normal operation again, as shown in the figure below:

ExitIntuitive
Figure 4. Cancelling an intuitive command

3. Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

3.1. Intuitive command prompt

3.1.1. Current implementation

The Intuitive Command Prompt feature is facilitated mainly by two classes: IntuitivePromptManager and IntuitiveEntryCommand.

IntuitiveEntryCommand extends Command, and represents the logic to be executed when the user enters an input during the execution of an intuitive command. The IntuitiveEntryCommand communicates with the Model interface in order to add an input into, or remove an input from the IntuitivePromptManager.

The IntuitivePromptManager exists to store the inputs entered by the user during the execution of an intuitive command, and once all prompts or fields of the intuitive command have been filled, uses the stored inputs to prepare a String that represents a non-intuitive command (e.g. add n/NAME p/PHONE …​) back to the AddressBookParser in order to execute this command.

The IntuitivePromptManager also has an ArgumentManager that determines how to keep track of the arguments for its respective intuitive command.

IntuitivePromptManager has six public-access methods that allow the Model to communicate with it. They are the following:

  • IntuitivePromptManager#addArgument(input): takes in a string input and stores it as an argument

  • IntuitivePromptManager#removeArgument(): removes the latest stored argument(s)

  • IntuitivePromptManager#getInstruction(): retrieves the instruction or prompt to be shown to the user (for the field that One Life is currently prompting the user for)

  • IntuitivePromptManager#retrieveArguments(): prepares and returns the String that represents the non-intuitive command, called when all fields have been filled

  • IntuitivePromptManager#isIntuitiveMode(): checks if One Life is currently executing an intuitive command

  • IntuitivePromptManager#areArgsAvailable(): checks if there are any arguments still being stored in the IntuitivePromptManager

With the above operations in mind, below is an example usage scenario of how an intuitive command works at each step. We will be using the example of an intuitive add command.

Start of Intuitive Command

The intuitive command first needs to be triggered:

Step 1. User wishes to add a new patient. User types add into the command prompt and submits.

Step 2. AddressBookParser parses the input and detects the add command word without any trailing arguments. Intuitive mode is triggered and a new IntuitiveEntryCommand is created.

Step 3. LogicManager executes the IntuitiveEntryCommand. IntuitiveEntryCommand interfaces with Model to add and store the user’s input in the IntuitivePromptManager.

Step 4. Model calls the IntuitivePromptManager to store the user’s input as an argument. Since the user’s input is the add command word, the IntuitivePromptManager triggers it’s intuitive mode - it creates the respective ArgumentManager (in this case it is an AddArgumentManager) and stores it in a variable called argumentManager.

Step 5. Model then calls the IntuitivePromptManager to retrieve the next prompt to be shown to the user. IntuitivePromptManager asks argumentManager to retrieve the correct instruction. This String instruction representing the prompt to be shown is then returned by IntuitivePromptManager and Model then proceeds to return this String instruction to the executing IntuitiveEntryCommand.

Step 6. IntuitiveEntryCommand uses the String instruction to create a new CommandResult, which is then returned to the LogicManager to be displayed to the user.

The following two sequence diagrams (Figures 11 & 12) describes the above process:

IntuitiveCommandWordSequenceDiagram
Figure 5. High level sequence diagram detailing interactions between Logic and Model
ArgumentManagerStartSequenceDiagram
Figure 6. Internal sequence diagram showing how IntuitivePromptManager interacts with argumentManager
Middle of Intuitive Command

As the intuitive command has now started and is in the midst of execution, the system prompts the user for an input for the next field:

Step 1. The system displays the instruction which prompts the user for the role of the person to be added. The user enters patient to indicate that the person added is a patient.

Step 2-3. These steps are similar to Steps 2-3 of the above section (Start of Intuitive Command), with the exception that the input is now patient

Step 4. Model calls the IntuitivePromptManager to store the user’s input as an argument. Since the intuitive command is already executing, the user’s input is stored as an argument in the arguments list. The currentArgIndex, which allows the IntuitivePromptManager to determine the what field it should prompt for next is incremented accordingly by the ArgumentManager:

IntuitiveInternalDiagram
Figure 7. How the arguments list in IntuitivePromptManager records arguments with currentArgIndex

Step 5-6. These steps are the same as that of the above section (Start of Intuitive Command)

End of Intuitive Command

Once all fields have been filled by the user, the system will exit intuitive mode as follows:

Step 1-3. These steps are the same as those of the above section (Start of Intuitive Command). Take note that this is the last field that the user has to fill.

Step 4. Model calls the IntuitivePromptManager to store the user’s input as an argument. The input is stored as an argument in the arguments list. The IntuitivePromptManager detects that this is the last field required to be filled and calls IntuitivePromptManager#exitIntuitiveMode() to signal the end of the intuitive command.

Step 5. Model retrieves the next prompt from the IntuitivePromptManager but since there are no more fields needing to be filled, IntuitivePromptManager returns a loading message to be displayed to the user, to inform the user that the intuitive command is complete and the arguments provided by the user are being processed

Step 6. LogicManager detects that the intuitive command has exited and that there are arguments stored in the IntuitivePromptManager. Using the Model interface, it requests to retrieve the arguments in the IntuitivePromptManager as a String line (representing a non-intuitive command).

Step 7. This String line is passed into the AddressBookParser to be parsed. The sequence flow from here is the same as if the user entered the non-intuitive version of the command.

The following sequence diagram describes Step 6 and onwards.

IntuitiveEndSequenceDiagram
Figure 8. High level sequence diagram showing how arguments are retrieved at the end of the intuitive command
Going Back

The user has the ability to undo the inputs that he enters into each field. This is known as going back, and is achieved when the user types /bk. The following usage scenario describes how this takes place:

Step 1. The user decides to undo his input for the previous field, and types /bk.

Step 2. The system behaves as per normal as mentioned above, treating /bk as a normal input.

Step 3. When IntuitiveEntryCommand#execute() is called, it detects that the input is the go back command /bk. It calls Model#removeIntuitiveEntry() to remove the input filled into the latest field.

Step 4. Model#removeIntuitiveEntry() calls IntuitivePromptManager#removeArgument(), and the IntuitivePromptManager removes the input filled into the latest field. currentArgIndex is decremented as accordingly by the ArgumentManager as shown in the code snippet below:

public void removeArgument() {
    if (currentArgIndex <= ArgumentManager.MIN_ARGUMENT_INDEX) {
        return;
    }

    currentArgIndex = argumentManager.removeArgumentForCommand(arguments, currentArgIndex);
}

Step 5. Model retrieves the instruction of the field indicated by the currentArgIndex of the IntuitivePromptManager. Execution continues normally as described in the above sections.

The following two sequence diagrams (Figures 15 & 16) describe the above process:

IntuitiveCommandPromptBackSequenceDiagram
Figure 9. High level sequence diagram showing going back ability
ArgumentManagerBackSequenceDiagram
Figure 10. Internal sequence digram showing going back ability

3.1.2. Commands & Argument Managers

The following XYZArgumentManagers inherit from ArgumentManager. They handle arguments for and represent the different commands as stated below:

  • AddArgumentManager: Represents the intuitive add command

  • DeleteArgumentManager: Represents the intuitive delete command

  • FindArgumentManager: Represents the intuitive find command

  • EditArgumentManager: Represents the intuitive edit command

  • ScheduleArgumentManager: Represents the intuitive schedule command

  • UpdateArgumentManager: Represents the intuitive update command