PROJECT: SSENISUB

Ui

Overview

This project portfolio serves to document my contributions to SSENISUB, a CS2103 (Software Engineering) project, as part of my Computer Science curriculum in National University of Singapore (NUS).

SSENISUB is a business management application which is used for managing employees' information within an organisation. Its name is inspired from the word "business", and is simply a palindrome of it. It is morphed from the given addressbook-level4 application as its base. The user interacts with it mainly using a Command Line Interface (CLI). In conjunction with the CLI, a Graphical User Interface (GUI) is used to make it more user-friendly, supported by coloured text and symbols. This application is written in Java with about 15 kLoC, and its GUI is created with JavaFX, CSS and HTML.

My main responsibility in SSENISUB is to implement commands (feedback and rate) that a manager would want to have to support a continuous review and tracking of his/her employees' performance throughout their time in the organisation. This is used to support making informed management decisions.

I also played a key role in creating an identity for SSENISUB by designing an icon and making it the face of the application.

Summary of contributions

  • Code contributed: [RepoSense for IamRENCE]

  • Major enhancement 1: added the ability to give ratings to staff stored inside the application

    • What it does: Allows the user to update a rating of a staff to keep track of his/her performance in the organisation.

    • Justification: This feature improves the product significantly because a user is provided with a way to keep track of his/her employees' performance, which is especially important during the year-end performance review. It potentially affects how much bonus or credit is given to the staff in the organisation.

    • Highlights: This enhancement looks similar to the add and edit command, but has to be made to execute asynchronous to these commands. In future releases, where users of different levels of authorisation are allowed to use different commands, this command would only be accessible to managers (or direct superiors). The reason is that they have the right to and are in the best position to give any rating to their staff.

  • Major enhancement 2: added the ability to give feedback to staff stored inside the application

    • What it does: Allows the user to give professional feedback to staff in the organisation, so that the staff knows what he/she is doing well in and to find out what areas of improvement he/she can engage in.

    • Justification: This feature, like the rate command, improves the product to a large extent because a user is provided with a way to inform his/her employees what to look out for in their performance so that they can improve themselves. Coupled with the rate command, a manager can make more informed reviews of his/her employees' performance. At the same time, employees can use the feedback assigned to them as motivation for continuous improvement, or as a wake up call for any bad performance. This can boost the organisation’s productivity as a whole.

    • Highlights: Just like the rate command, the feedback command is run non-parallel to the add and edit command due to future user authorisation implementations. Another highlight of this command is that users cannot enter profanities (even if it is entered in leetspeak). Designing an efficient way to check for profanities proved to be a very tough task: Whether to base the runtime on input length or the number of profanities to be rejected. A detailed analysis had to be done to make a choice.

    • Credits: [Simple Profanity Filter by PimDeWitte]

  • Other contributions:

    • Project management:

      • Checked v1.1 - v1.4 (4 releases) before they got released them on GitHub.

    • Enhancements to existing features:

      • Updated the application icon (Pull request #42).

      • Wrote additional tests for existing features to increase coverage from 93.4% to 93.6% (Pull request #58).

    • Bug fixes:

      • Fixed bugs commands that allowed for inputs that otherwise should have been rejected (Pull request #58).

      • Fixed overall UI/code bug where "Address Book"/"AddresBook" is displayed or used instead of our application "SSENISUB" (Pull request #107).

    • Documentation:

      • Updated existing contents of the User Guide: #101, #102, #109.

      • Updated existing contents of the Developer Guide: #29, #109.

    • Community:

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.

Rating a staff: rate

Rates an existing staff in SSENISUB
Format: rate INDEX r/RATING

  • Rates the staff at the specified INDEX. The index refers to the index number shown in the displayed staff list. The index must be a positive integer 1, 2, 3, …​

  • The rating field must be provided.

  • Ratings can only be from 1 - 10.

  • Existing values will be updated to the input values if they are different.

Examples:

  • rate 3 r/8
    Rates the 3rd staff of a rating 8.

Giving feedback to a staff: feedback

Provides feedback for an existing staff in SSENISUB
Format: feedback INDEX fb/FEEDBACK

  • Updates the feedback of the staff at specified INDEX. The index refers to the index number shown in the displayed staff list. The index must be a positive integer 1, 2, 3, …​

  • The feedback field must be provided.

  • Profanities are not allowed, even if it is encapsulated within a word.

  • Profanities written in leetspeak will be caught as well.

Examples:

  • feedback 1 fb/You are great!
    Gives the 1st staff a feedback of "You are great!".

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.

Rate command feature

Introduction

We have implemented a rate command feature as an enhancement, which focuses on the Logic component. A Rating class is implemented to support this, which the Person class is dependent on. This command allows users, especially for managers to update ratings of employees within an organisation.

This command differs from the add and edit command, because users cannot simply add an employee with a rating through the add command or edit an employee’s rating through the edit command.
Any updates to an employee’s rating should only be done by a person of authority, i.e. Manager.

Current Implementation

The rate command, as mentioned, executes asynchronous to the add and edit command. Upon adding an employee, a Rating.DEFAULT_INITIAL_RATING with a default value of 0, is initialised on the Person and then saved.

There are 2 validation regular expressions found in the Rating class:

  • VALIDATION_REGEX which checks for integer values from 0 - 10 of Rating which have already been added. 0 is included as there may be a case when a Person has already been added but his/her Rating has yet to be updated.

  • VALIDATION_INPUT_REGEX which checks for integer values from 1 - 10 of Rating to be added by users with the rate command.

Given below is a sequence diagram shows how the rate operation works:

RateSequenceDiagram

Feedback command feature

Introduction

Similar to the rate command, we have implemented a feedback command feature as an enhancement, which also focuses on the Logic component. A Feedback class is implemented to support this, which the Person class is dependent on. This command allows users, especially for managers, to give feedback to their employees within an organisation for them to know what to look out for in their performance and improve themselves.

This command also differs from the add and edit command, because users cannot simply add an employee with a feedback through the add command or edit an employee’s feedback through the edit command. Every employee added will start off without any feedback assigned to him/her.
Any updates to an employee’s feedback should only be done by a person of authority, i.e. Manager.

Current Implementation

The feedback command, like the rate command, executes nonparallel to the add and edit command. Upon adding an employee, a FEEDBACK.DEFAULT_INITIAL_FEEDBACK with a default value of "-NO FEEDBACK YET-", is initialised on the Person and then saved.

Given below is a sequence diagram shows how the feedback operation works:

FeedbackSequenceDiagram

A simple profanity is implemented in the Feedback class, which checks for any profanity found within the feedback input (Adapted from Simple Profanity Filter). The list of English and Singlish profanities (Profanity List) used can be subjected to expansion and modification. The filter works by iterating through the whole input to find any possible sequence of words (no re-ordering) that match any profanity found within the profanity list. As such, runtime will be dependent on input length rather than profanity list length.

Given below is a sequence diagram to show how the profanity filter operation works (This extends from the previous diagram, which omitted the part where Feedback is called by FeedbackCommandParser):

FeedbackProfanitySequenceDiagram

Noteworthy Features:

  • The filter is case insensitive.

  • In the profanity list, profanities are separated into rows with the format: [THE_BAD_WORD], [IGNORE_IN_COMBINATION_WITH]

    • [THE_BAD_WORD] is the profanity to filter out.

    • [IGNORE_IN_COMBINATION_WITH] can be empty, or contain a series of 1 or more words (separated by commas) that [THE_BAD_WORD] can be used with, e.g. paki, pakistan. "paki" is a racial slur and will be rejected, but if "pakistan", a country name, is entered, "pakistan" will be accepted even though it contains "paki".

    • Each iteration ends when the end of the string is reached or the length of the current substring checked reaches the longest profanity string length within the profanity list (For increased performance).

  • Any leetspeak in the input will be replaced by its appropriate characters before the check, i.e. "H3ll0" will be corrected to "Hello".

This profanity filter is quite basic and can be bypassed because of replacing leetspeak. For example, "2 girls 1 cup" is considered as inappropriate, but the replacement of "1" to "i" will cause the input to be accepted. An easy solution is to hard code the check of this input, but there will be many other examples like this that we would have to hard code for. As such, we have decided to accept this as a minor shortfall of this implementation.

Given below is a sample run of the profanity filter with a feedback input of "u suckz":

  • Iteration 1:

    • 1a: "u": Not a profanity (No match with line in profanity list).

    • 1b: "u ": Not a profanity (No match with line in profanity list).

    • …​

    • 1g: "u suckz": Not a profanity (No match with line in profanity list).

  • Iteration 2:

    • 2a: " ": Not a profanity (No match with line in profanity list).

    • 2b: " s": Not a profanity (No match with line in profanity list).

    • …​

    • 2f: " suckz": Not a profanity (No match with line in profanity list).

  • Iteration 3:

    • 3a: "s": Not a profanity (No match with line in profanity list).

    • 3b: "su": Not a profanity (No match with line in profanity list).

    • 3c: "suc": Not a profanity (No match with line in profanity list).

    • 3d: "suck": Profanity! (Matches with a line in profanity list). Added to a list of bad words found.

    • 3e: "suckz": Not a profanity (No match with line in profanity list).

  • …​

  • Iteration 7:

    • 7a: "z": Not a profanity (No match with line in profanity list).

  • The resulting list has only 1 value: "suck" and the input will be rejected since there is at least 1 profanity found.

Design Considerations

How to implement the profanity filter

To ensure fast retrieval, a HashMap is used to store profanities to be rejected from the data file before using it to check if the input contains any profanities inside.

  • Alternative 1 (current choice): Check every substring of the input to see if it matches any profanity-to-reject within the HashMap.

    • Pros: O(1) runtime per substring when checking whether a particular substring of the input.

    • Cons: Runs for O(n2) time, where n is the number of characters in the input.

      • While this may look daunting, we have a character input limit on Person attributes (feedback included) of 50. As such, there is an imposed upper bound on the performance time, preventing any significant decline in performance.

      • Also, one optimisation method implemented (mentioned in Feedback noteworthy features) is ending the iteration when the length of the longest string within the profanities-to-reject is reached. This improves the performance time to O(ln), where l is length of the longest profanity-to-reject.

  • Alternative 2 : Check every element in HashMap to see if it is contained within the input.

    • Pros: Runs for O(n) time per element in HashMap using the String.contains() method, where n is the number of characters in the input, and is capped at n ≤ 50 (Mentioned in Alternative 1).

    • Cons: Runs for O(nm) time, where m is the number of elements in the HashMap. m can increase infinitely by extending the list of profanities-to-reject (i.e. Adding profanities of other languages, adding newly created profanities, adding profanities that have been overlooked, etc.)

      • Hence, this alternative is not as efficient as O(lm) in Alternative 1 as l can be capped but m may not.