Project Portfolio for ORGANice
The purpose of this project portfolio is to present my main contributions to ORGANice.
1. Introduction
This section covers the project scope and description, followed an explanation of the formats used.
1.1. Project scope
ORGANice is the product of a software engineering project done by a team of 5 students, including myself, who are second-year Computer Science students from the National University of Singapore (NUS).
Under a two-month-long time frame, we conceptualised ORGANice and molded it from an existing application, known as "Address Book", that stores and manages people’s contact information.
My role in this project is to design and write the code for the list
and sort
features for ORGANice, and to offer advice for the design aspect of the application.
For the languages used, ORGANice is written in Java while its Graphical User Interface (GUI) is written in JavaFX.
1.2. Project description
ORGANice is a Command Line Interface (CLI) desktop application, meaning that user interaction is mainly through typing in commands. This application is targeted at hospital administrators and its main features include storing hospital information, finding compatible donors for patients awaiting organ transplants, and following up on administrative matters related to the organ matching process.
ORGANice has the following features:
-
Maintain the information of doctors, donors, and patients using
add
andedit
-
Find information quickly using
find
andlist
-
Match compatible organ donors with patients and sort the matches using
match
andsort
-
Keep track of patient-donor pairs slated for further compatibility tests using
processing
and subsequent administrative tasks usingprocessingmarkdone
-
Mark patient-donor pair as
done
to remove from future matching results
1.3. Meaning of the formats used
The following is a list of various formats used and what they mean:
-
sort
— Purple texts are technical terms used in this project. -
#153 — Blue underlined texts consist of a link that opens up a relevant webpage.
2. Summary of Contributions
This section elaborates on the enhancements I did to ORGANice with the relevant links (in blue).
-
Major enhancement: Added the ability to sort matches according to different criteria. (Pull request #145)
-
What it does: Allows the user to sort patient-donor pairs according to compatibility rate, the priority of the patients, or donors' organ expiry date.
-
Justification: Helps the hospital to make more informed decisions after knowing which pairs are the most compatible, which patient to prioritize, and which organs are expiring soon respectively.
-
Highlights: Able to add in more sorting options in future enhancements. The implementation is challenging as it required an in-depth analysis of how the match feature is implemented.
-
-
Minor enhancement: Added a list feature that allows the user to list down all persons or persons of a specified type in ORGANice. (Pull request #113)
-
Minor enhancement: Added an organ class to ORGANice. (Pull request #86)
-
Minor enhancement: Designed the logo of ORGANice, and updated the application window to display title and logo. (Pull request #136)
-
Code contributed: You may click on the following link to see a sample of my code. (Functional and Test code)
-
Other contributions:
-
Project Management
-
Created issues on the project board to keep track of tasks to be done.
-
-
Enhancements to existing features
-
Fixed bug related to the list feature. (Pull request #236)
-
-
Documentation
-
Updated information about our team in the "About Us" section of ORGANice. (Pull request #11)
-
Authored the sections that guide users through the features 'Edit', 'List', 'Sort' and 'Help' in the User Guide. (Pull request #133)
-
Authored the implementations and use cases of the 'List' and 'Sort' features in the Developer Guide. (Pull requests #131, #153)
-
-
Community
-
3. Contributions to the User Guide
This section showcases my ability to write documentation targeting end-users through an excerpt of what I have written for the User Guide,
and this includes the sort
, list
, help
and edit
features.
{Start of the excerpt from User Guide}
3.1. Sorting matches: sort
After using the match command, you can sort the list of matches to determine which patients to prioritize for an organ transplant.
The sort command can only be used after a match command to sort the resulting list of patient-donor pairs generated. There are three criteria in which you can sort the matches, namely:
-
Sorting based on donor’s organ expiry date
-
Sorting based on priority
-
Sorting based on the compatibility rate of match
These criteria will be further explained below.
Note that only one criterion can be used in a single sort command.
3.1.1. Sorting based on donor’s organ expiry date
To find out which organs are expiring soon, you can sort the list of matched donors based on the donor’s organ expiry date (from the earliest to the latest expiry date).
Format: sort expiry
For example, after running a match command on a specific patient with match ic/NRIC
, you will get the list of donors that are compatible with said patient.
You can then run sort expiry
to obtain the list of donors with earlier organ expiry dates near the top of the list.
3.1.2. Sorting based on priority
To determine which patient to prioritize for an organ transplant, you can sort the list of matched patients based on their priority (from highest to lowest). You may refer to [Glossary] to understand what priority means.
Format: sort priority
For example, after running match ic/all
, you will obtain a list of patients.
You can then run sort priority
to obtain the list with higher priority patients near the top of the list.
Note that in the case where patients have the same priority, those with more matched donors will be displayed first. If these two factors are the same for a group of patients, they will be displayed according to their names in alphabetical order.
3.1.3. Sorting based on the compatibility rate of match
To determine which patient-donor pair is the most compatible, you can sort the list of compatible donors of that patient based on the compatibility rate of the match (from highest to lowest). You may refer to [Glossary] for more information on the compatibility rate.
Format: sort rate
Take for instance, after running a match command on a specific patient with match ic/NRIC
, you will get a list of donors that are compatible with said patient.
You can then run sort rate
to obtain the list of donors with higher compatibility rates near the top of the list.
3.2. Listing persons: list
This list command can show you the list of persons in ORGANice.
3.2.1. Listing all persons
Simply type list
in the Command Box and press Enter. ORGANice will show you all patients, doctors, and donors present in the system.
3.2.2. Listing persons of a specified type
If you wish to see a certain type of person only, you can provide the type parameter in the list command.
Optional parameter: Type - t/TYPE
For instance, if you only want to see all doctors, you can enter the following:
list t/doctor
. Likewise, you can change the type parameter in the same manner to see only patients or donors.
3.3. Viewing help: help
There may be times where you need more information on how ORGANice works. To access the user guide of ORGANice, you can do the following:
Simply type help
in the Command Box and press Enter. You will see a link given in a pop-up "Help" window.
You may click on the Copy URL button and paste it in a browser to see our user guide for more information on how to use ORGANice.
To exit the window, click the x button found near the top of the window to close it and return to the default display.
3.4. Editing a person’s attribute: edit
If you want to make any changes to a person’s attribute, you can edit the information using an edit command. If there are multiple attributes to change, you can do so in the same edit command.
The format is such that after the edit
keyword, provide the person’s NRIC, followed by the attribute(s) that you want to change in the edit command.
Format: edit NRIC
followed by attributes to update
For instance, if you want to change a patient’s phone number to 91234567, you can provide his or her NRIC followed by the new phone number
as follows: edit S8732457G p/91234567
.
You can only make changes to attributes that the person has. For example, you cannot change a doctor’s age because a doctor does not have that attribute in ORGANice.
Besides that, some attributes cannot be edited. These include:
-
NRIC
-
Type
You may want to refer to [List of Attributes] to see what attributes apply to each type of person in ORGANice.
{End of the excerpt from User Guide}
4. Contributions to the Developer Guide
This section showcases my ability to write technical documentation and to visually represent a system using
Unified Modelling Language (UML) diagrams in the Developer Guide. The sequence shown in the excerpt below will be use cases for
list
and sort
features, followed by their implementations, and lastly, the Model
class diagram that I have updated.
{Start of the excerpt from Developer Guide}
4.1. Use case: List all patients/donors/doctors
MSS
-
User requests to list patients/donors/doctors.
-
ORGANice shows the list of patients/donors/doctors.
Use case ends.
Extensions
-
1a. ORGANice detects an invalid parameter.
-
1a1. ORGANice returns error message.
Use case ends.
-
4.2. Use case: Sort list according to priority/rate/expiry
MSS
-
User requests to sort the list of donors of a particular patient.
-
ORGANice sorts the list of donors according to the parameters.
Use case ends.
Extensions
-
1a. ORGANice detects invalid parameter(s).
-
1a1. ORGANice prompts for valid parameter(s).
-
1a2. User enters correct parameter(s).
Steps 1a1-1a2 are repeated until the data entered are correct.
Use case resumes at step 2.
-
4.3. List feature
This section describes how the list feature is implemented.
The list feature is implemented using the ListCommand(Type type)
. When the list command is executed,
the method ModelManager#updateFilteredPersonList(Predicate<Person> predicate)
takes in a predicate
to decide what type of Person
to show on the filteredPersons
list.
Therefore, in addition to the existing PREDICATE_SHOW_ALL_PERSONS
predicate, three other predicates are introduced
in the Model
interface to update the list.
The code snippet below shows what these predicates are:
/** {@code Predicate} that always evaluate to true */
Predicate<Person> PREDICATE_SHOW_ALL_PERSONS = unused -> true;
/** {@code Predicate} that always evaluate to true if person is a doctor */
Predicate<Person> PREDICATE_SHOW_ALL_DOCTORS = person -> person.getType().isDoctor();
/** {@code Predicate} that always evaluate to true if person is a donor */
Predicate<Person> PREDICATE_SHOW_ALL_DONORS = person -> person.getType().isDonor();
/** {@code Predicate} that always evaluate to true if person is a patient */
Predicate<Person> PREDICATE_SHOW_ALL_PATIENTS = person -> person.getType().isPatient();
The activity diagram below illustrates what happens when a user uses the list command.
When the user enters a list command, the result differs depending on the parameter of the command.
If there is no parameter after 'list', ORGANice will simply list all existing doctors, patients, and donors on the list.
If there is a parameter, ORGANice will check if it is a valid TYPE
parameter and display the correct list of persons
that corresponds to this type.
If the parameter is not valid, an error message will be displayed to indicate that the command is invalid.
4.4. Sort feature
This section describes how the sort feature is implemented.
Sorting is done by using Comparators
in the Logic
component and makes use of the SortCommand
.
This command only works after a MatchCommand
is called by the user, because it takes in listOfMatches
returned
from calling a MatchCommand
. Importantly, this listOfMatches
is an ObservableList
, which cannot be modified.
Therefore, it makes use of SortedList
to wrap around the ObservableList
so that the list can be modified by sorting.
Thus far, the sort command can only take in one String
parameter, but more methods can be added in the future for more sorting options.
Three methods of sorting are implemented to sort based on the following categories:
-
Sorting based on donor’s organ expiry date with
sort expiry
-
Sorting based on priority with
sort priority
-
Sorting based on compatibility rate of the match with
sort rate
These three methods' implementation will be further elaborated upon below.
4.4.1. Sort by Expiry
Sorting by Expiry sorts a list of MatchedDonor
with the ModelManager#sortByOrganExpiryDate()
method.
In this method, the ExpiryComparator
is used to compare two matched donors' organ expiry dates, and this requires
the OrganExpiryDate
of the donors to be parsed into a data format that can be compared.
4.4.2. Sort by Compatibility Rate
Sorting by Compatibility Rate sorts a list of MatchedPatient
using the ModelManager#sortBySuccessRate()
method.
The CompatibilityRateComparator
is created to compare two matched patients' rate of compatibility for the match.
Given below is a Sequence Diagram to show the interactions with the Logic
component when executing the execute(sort rate)
method,
assuming the user has entered a valid match ic/NRIC
command before this.
sort rate
commandAfter the command is given by the user, it would be parsed by the AddressBookParser
.
The SortCommandParser
then parses the parameter rate
and a SortCommand
is created.
The LogicManager
will then execute the command and call the sortByCompatibilityRate()
method from the ModelManager
.
The list of MatchedPatient
will then be sorted based on their match’s compatibility rate.
4.4.3. Sort by Priority
Sorting by Expiry sorts a list of MatchedPatient
using the ModelManager#sortByPriority()
method.
In this method, there are two other comparators created in addition to the Priority Comparator
,
namely the NameComparator
and the NumOfMatchesComparator
. These two comparators serve as tie-breakers in cases where
patients have the same priority. In other words, for patients of the same priority, those with more matched donors will be displayed first.
If these two factors are the same for a group of patients, they will be displayed according to their names in alphabetical order.
Under the sortByPriority()
method, the order of applying the comparators to the list of patients
is, firstly, the 'NameComparator', followed by NumOfMatchesComparator
, and lastly, the PriorityComparator
.
This means that the patients are first sorted by names in alphabetical order, followed by the number of matched donors they have
in descending order (highest to lowest), and then their priority level in descending order (from high, to medium, to low).
All three comparators makes use of the compareTo
method under the Comparable
class, which can sort in lexical order for String,
and numeric order for Sorting integers.
In particular, the PriorityComparator
makes use of the compareTo
method implemented in the Priority
class.
A code snippet of this method is shown below.
@Override
public int compareTo(Priority priority) {
Integer thisPriorityNumber = 0;
Integer otherPriorityNumber = 0;
if (this.isHighPriority()) {
thisPriorityNumber = 3;
} else if (this.isMediumPriority()) {
thisPriorityNumber = 2;
} else if (this.isLowPriority()) {
thisPriorityNumber = 1;
}
if (priority.isHighPriority()) {
otherPriorityNumber = 3;
} else if (priority.isMediumPriority()) {
otherPriorityNumber = 2;
} else if (priority.isLowPriority()) {
otherPriorityNumber = 1;
}
return thisPriorityNumber.compareTo(otherPriorityNumber);
}
This implementation is the result of using String
to represent the different priorities in the Priority
class.
Therefore, they are converted into Integer
for easier comparison. An alternative solution would be to make use of
Enum
class to define each priority so that this compareTo
method implementation can be simplified.
4.4.4. Design considerations
This section will explain two aspects considered in designing the sort feature.
Aspect: Method of storing the sorted result
-
Alternative 1 (current choice): Use
SortedList
.-
Pros: Fast iteration time of O(n * log n), which is important for ORGANice to load and display the sorted result, and more harmonious with current implementations (able to wrap
ObservableList
and sort the content). -
Cons: Not the most efficient algorithm for insertions or deletions, but ORGANice does not require them.
-
-
Alternative 2: Use
ArrayList
.-
Pros: Fast index-based access and works on any
Collection
class. -
Cons: Slower than
SortedList
as it takes O(n) time to iterate and display the results.
-
Aspect: Method of sorting
-
Alternative 1 (current choice): Use
Comparator
andComparable
.-
Pros: Simpler implementation as able to make use of existing methods in ORGANice such as
setComparator
. -
Cons: More coding involved.
-
-
Alternative 2: Use
Collections.sort()
.-
Pros: Has a time complexity of O(n*log(n)) which is relatively fast.
-
Cons: Cannot make use of existing methods in ORGANice that work for Comparator.
-
4.5. Model component
{End of the excerpt from Developer Guide}