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:
-
Bug fixes:
-
Documentation:
-
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
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
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 ofRating
which have already been added. 0 is included as there may be a case when aPerson
has already been added but his/herRating
has yet to be updated. -
VALIDATION_INPUT_REGEX
which checks for integer values from 1 - 10 ofRating
to be added by users with the rate command.
Given below is a sequence diagram shows how the rate operation works:
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:
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
):
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.
-
-