1. PROJECT: One Life


1.1. Overview

This Project Portfolio is intended to document my contributions towards One Life. These contributions include functional and non-functional code, documentation, user interface and numerous other aspects of the project.

One Life is a desktop-based medical database and medical information management application used for storing and displaying data related to patients and doctors. One Life aims to improve the efficiency of administrative processes in medical institutions. It was developed as part of the module requirements for CS2103T (Software Engineering).

The user interacts with it 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: Enhanced the ability to find Person with selected attributes instead of only with their Name.

    • What it does: This feature allows the user to find all Person containing specified keywords. Users may combine multiple keywords from different fields to increase the search accuracy.

    • Justification: This feature improves the product significantly because it reduces the amount of time needed to find all relevant Person and perform other operations on their information fields.

    • Highlights: This enhancement was deceptively challenging. Even though it builds upon existing procedures, a large amount of modification was necessary to ensure that users are able to enter the arguments in any preferred order.

  • Minor enhancement: Modified the find command to reject invalid input and prompt the user for proper input using a format guide.

  • Code contributed: [Functional code] [RepoSense]

  • Other contributions:

    • Project management:

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

      • Set up Travis and AppVeyor badge for tracking of project build. (Pull request #49)

    • Enhancements to existing features:

      • Fixed bugs arising from modification of the GUI. (Pull request #183)

    • Documentation:

      • Modified README, AboutUs and ContactUs to match project specifications and team information. (Pull request #36)

      • Modified build.gradle to reflect our project and removed elements of AddressBook-Level4 from the documentation website. (Pull request #150, #153)

    • Community:

      • Reviewed pull requests (with non-trivial review comments). (Pull request #128)

      • Reviewed and addressed raised issues. (Issue #170, #174)

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. Locating person by any attribute: find

There are two types of Find Commands: Global Find and Specific Find. They can be used in conjunction with one another.
Format: find [PREFIX] KEYWORDS [NEXT_PREFIX] [MORE_KEYWORDS]

In order for a Person to show up on find, the Person must match all attributes in the input.
(i.e. find n/alex r/doctor will show all Doctor named Alex. If another Alex is not a Doctor, he will not be shown.)

2.1.1. Global Find

Global Find is a search on all attributes of all Person in the database.

It is performed when:

  • no Prefix is included in the input, or when

  • keywords are included before the first valid Prefix.

When performing Global Find with more than one separate keyword, users can simply separate them using a [SPACE]. The Find Command will interpret the input as separate words to be searched globally.

Examples:

  • find kang
    Displays all Person with kang in any of their attributes.

  • find kang r/doctor
    Displays all Person with kang in any of their attributes and whom is a Doctor. This is an example of Global Find used in conjunction with Specific Find.

  • find alex doctor
    Displays all Person with alex or doctor in any of their attributes.

The images below illustrate the utilisation of Global Find:

FindCommandUserGuideGlobal1
Figure 1. Global find command
FindCommandUserGuideGlobal2
Figure 2. Global find command with specific find command
FindCommandUserGuideGlobal3
Figure 3. Global Find command with multiple keywords

2.1.2. Specific Find

Specific Find is a search on attributes specified by the user. (i.e. Name, Phone etc).

It is performed when a Prefix is specified in the input field.
Below is a list of all searchable attributes and their corresponding Prefix:

Table 1. Table of searchable prefixes

Attribute

Prefix

Name

n/

NRIC

ic/

Phone

p/

Email

e/

Address

a/

Role

r/

Tag

t/

Medical Department

md/

Medical Record

mr/

Search keywords must be entered behind a Prefix whenever a Prefix is used in the input. A command like find n/[BLANK] is not a valid input.
The Prefix entered must also be valid.

Examples:

  • find t/friends
    Displays all Person with the Tag labelled friends.

  • find t/friends r/doctor
    Displays all Person with the Tag labelled friends and whose Role is Doctor.

  • The images below illustrate the utilisation of Specific Find.

FindCommandUserGuideSpecific1
Figure 4. Specific find command
FindCommandUserGuideSpecific2
Figure 5. Specific find command with additional prefixes
FindCommandUserGuideError
Figure 6. Examples of invalid input for specific find command
  • Find is case-insensitive. e.g. nelvin will match Nelvin.

  • In Global Find, Person containing any of the given keywords in any of his/her attributes will be displayed. e.g. find doctor nelvin will cause all Doctor and Nelvin Tan to be displayed.

  • In Specific Find, the specified attribute of the Person must contain the searched keyword to be displayed. e.g. find n/Gary Goh will display Gary Goh but not Kenneth Goh

  • In the event that the user wants to specify more than one keyword to be seperately searched in a specified attribute, for example if the user wants to find all Person with Name Kang Tze or Triston, he must separate the names using two Name Prefix. e.g. find n/Kang Tze n/Triston displays Ng Kang Tze and Triston Pang.

  • An illustration of a more complicated find command is find friends n/Kang Tze n/Triston r/doctor, which displays all Person with friends in their attributes, has name containing either Kang Tze or Triston, and whom is a Doctor.

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. Find command feature

3.1.1. Current implementation

The find mechanism is facilitated by FindCommand, FindCommandParser and PersonContainsKeywordPredicate. FindCommand extends from Command, FindCommandParser implements Parser and PersonContainsKeywordPredicate implements Predicate. The key operation implemented is FindCommand#execute.

Given below is an example usage scenario and how the find command mechanism behaves at each step.

Step 1. The user wants to find all Person whom have a friends Tag, with Name either Alex or Bernice by executing find n/Alex n/Bernice t/friends.

Step 2. FindCommandParser will parse the input and verify that is it valid before creating a PersonContainsKeywordsPredicate, which is passed into FindCommand. Then, FindCommand is returned.

  • PersonContainsKeywordPredicate takes in a HashMap of Prefix mapped to an ArrayList of search parameters. The code snippet below illustrates how a FindCommand is created:

public FindCommand parse(String args) throws ParseException {
        ...
        // Performs checks to see if the arguments entered are valid.
        ...
        // Process arguments into a HashMap personSearchKeywords which is used to create a PersonContainsKeywordsPredicate to be passed into FindCommand.
        ...
        return new FindCommand(new PersonContainsKeywordsPredicate(personSearchKeywords));
    }
  • PersonContainsKeywordPredicate tests if a Person should appear when searched by iterating through each of the keys in the HashMap and returning true if all of the Person 's attributes match at least 1 of the entries in each key’s ArrayList. The image below illustrates the list of Person that return true for PersonContainsKeywordPredicate#test after the user input find n/Alex n/Bernice t/friends.

FindCommandDeveloperGuidePredicate
Figure 7. PersonContainsKeywordPredicate test result
  • As can be seen in the image above, Person at index 0 and index 2 have at least 1 entry in Name and Tag that match the required search parameters. Therefore, they will be shown in the result list. Even though Person at index 1 has a match in the Name attribute, he does not have a friends Tag and is therefore not shown.

If there is no input after the "find" keyword, IntuitiveEntryCommand will be triggered, which will prompt the user to input search parameters.

Step 3. FindCommand will then be executed.

Step 4. Model#updateFilteredPersonList() will be called, which uses PersonContainsKeywordPredicate to update Model to show all Person that contains the searched parameters.

The following activity diagram summarises what happens when a user launches the application:

FindCommandDeveloperGuideSequenceDiagram
Figure 8. Find command sequence diagram

3.1.2. Design considerations

Aspect: How to input search fields
  • Alternative 1 (current choice): Allow users to perform searches by specifying certain keywords of interest. (For example: Name : n/, Phone: p/)

    • Pros: It results in a powerful and precise search function by providing the user the option to specify exactly which Person attributes are of interest.

    • Cons: It may be difficult for newer users to remember the shortcuts that represent the attributes of interest.

  • Alternative 2: Generalise the search function by searching through all fields and providing the most relevant information through predictive search.

    • Pros: It provides an even more powerful search function that is both simple to use and accurate.

    • Cons: It is incredibly difficult to implement such a search function without the use of machine-learning algorithms or an internet connection.