Overview
My team of 4 software engineering students and I were tasked with enhancing a basic command line interface desktop addressbook application for our Software Engineering project. We chose to morph it into an activity tracking bill-splitting system called SplitWiser.
This enhanced application enables people who participate in group activities together with shared expenses to split the cost evenly without the hassle of manual calculation.
This is what our project looks like:
My role was to design and write codes for the invite
, disinvite
and delete
features. The following sections illustrate
these enhancements in more detail, as well as the relevant documentation I have added to the user and developer guides in relation to these enhancements.
Note the following formatting used in this document.
delete
: A grey highlight indicates that this is a command that can be inputted into the command line and executed by the application
Summary of contributions
-
Major enhancement: added the ability to invite contacts to current viewed activity
-
What it does: allows the user to
invite
multiple contacts at once to the current viewed activity. -
Justification: This feature improves the product significantly because the participants in an activity is not static as people can join midway during an activity and the app should provide a convenient way to
invite
them without creating a new activity. -
Highlights: This enhancement affects existing commands and commands to be added in future. The implementation was challenging due to the fact that it depends on the user’s screen.
-
-
Major enhancement: added the ability to disinvite contacts from current viewed activity
-
What it does: allows the user to
disinvite
multiple contacts at once from the current viewed activity. -
Justification: It is sort of an "undo" function if user mistakenly invited the wrong person to an activity. Since
invite
allows multiple invitees at once, an "undo" function will be inconvenient as it removes everyone that was invited previously,disinvite
allows user to remove particular participants that was invited mistakenly to the activity conveniently. -
Highlights: This enhancement affects existing commands and commands to be added in future. The implementation was challenging due to the fact that it depends on the user’s screen.
-
-
Major enhancement: added the ability to delete contact/activity/expense in an activity
-
What it does: allows the user to
delete
contact/activity or soft-delete expense one at a time. -
Justification: This feature improves the product significantly especially for the deletion of expense. Since money is a sensitive issue, the soft deletion of expense allows the expense to still be visible but striked-off so it remains as a history for accountability.
-
Highlights: This enhancement affects existing commands and commands to be added in future. The implementation was challenging due to the fact that it depends on the user’s screen.
-
-
Code contributed: Functional and test codes
-
Other contributions:
-
Enhancements to existing features:
-
Enhanced
delete
command to delete contacts, activities, expenses based on displayed screen (Pull requests #196) -
Implemented
invite
anddisinvite
command to invite or disinvite participants from current viewed activity (Pull requests #121, #108) -
Wrote additional tests for
delete
,invite
anddisinvite
(Pull requests #196, #121, #108, #136)
-
-
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. |
Inviting contacts to an activity: invite
This command invites the contacts specified to the current viewed activity.
Format: invite p/PERSON …
Example:
Suppose you have already created an activity with Alice, Bob and Carl in it.
activity t/Holiday Trip p/Alice p/Bob p/Carl
And you have friends that want to join an activity midway.
To invite:
Step 1: Type invite
into the command box and specify the contacts you want to invite from the contact list with the p/
prefix e.g. invite p/Mary p/John p/Carl
and press Enter
to execute it.
Step 2: Observe the output in result box and the activity details box.
The invite command only invites to current viewed activity.if there is no current viewed activity, there will be an error. The invite command only invites contact that exists in the contact list.If the specified contact does not exist in the contact list, then the contact cannot be added and a warning message will be shown. Multiple contacts can be invited at once. Contact that already exists in activity cannot be invited again. |
Disinviting contacts from an activity: disinvite
This command disinvites the contacts specified from the current viewed activity.
Format: disinvite p/PERSON …
Example:
Suppose you have an activity with the same participants but with an expense shared by Alice, Bob and Carl
And you feel that the activity has too many participants that do not participate in any event, thus having no shared expense and you decided to remove them.
To disinvite:
Step 1: Type disinvite
into the command box and specify the contacts you want to disinvite from the activity with the p/
prefix e.g. disinvite p/Mary p/John p/Carl
and press Enter
to execute it.
Step 2: Observe the output in result box and the activity details box.
The disinvite command only disinvites from current viewed activity.if there is no current viewed activity, there will be an error. The disinvite command only disinvites contact that exists in the activity.If the specified contact does not exist in the activity, then a warning message will be shown. Multiple contacts can be disinvited at once. Contact that involves in any expense cannot be disinvited. If a contact is involved in any expense, he cannot be disinvited. |
Deleting a contact, activity or expense: delete
Deletes the contact/activity/expense at the specified index from the current display.
Format: delete INDEX
If current display is listing contacts e.g. list c/
, the contact at that specified INDEX
will be deleted if he/she is not involved in any activity.
If current display is listing activities e.g. list a/
, the activity at that specified INDEX
will be deleted.
If viewing an activity instead e.g. view a/1
, it will soft-delete the expense* at that INDEX
.
If the current display is not any of the above displays mentioned, error will be thrown.
Examples:
-
delete 2
If viewing the list of contacts, deletes the 2nd person by index if he/she is not involved in any activity. -
delete 1
If viewing the list of activities, deletes the 1st activity by index. -
delete 1
If viewing a particular activity, fades (soft-deletes) the 1st expense by index.
Deletes the entry at the specified INDEX .The INDEX refers to the index number shown in the displayed list of contacts/activities/expenses.The INDEX must be a positive integer 1, 2, 3, …Expenses cannot be completely deleted. It will instead be faded (but still visible) in the activity view. |
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. |
Invite/Disinvite feature
Implementation
The invite/disinvite mechanism is facilitated by Activity
.
It extends AddressBook
with an ActivityBook
, stored internally as an activityList
. Additionally, it implements the following operations:
-
Activity#invite()
— Invites a person to the activity. -
Activity#disinvite()
— Disinvites a person from the activity.
These operations are exposed in the Activity
class as Activity#invite()
and Activity#disinvite()
respectively.
Given below is an example usage scenario and how the invite/disinvite mechanism behaves at each step.
Step 1. The user launches the application for the first time. SplitWiser
will be initialized with the initial address book and activity book state.
Step 2. The user executes activity t/breakfast p/David
command to create an activity named breakfast with David
as the sole participant which is stored in the activityList
.
Step 3. The user executes invite p/Louis p/Mary…
to invite more participants into the current viewed activity. The invite
command calls Activity#invite()
which then modifies the activityList
with the new participants and is stored in the ActivityBook
.
The following sequence diagram shows how the invite operation works:
The lifeline for InviteCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
Step 4. The user decides that inviting some contacts was a mistake or they has not been involved in any of the expenses in the activity. Hence the user decides to remove them from the activity by executing the disinvite
command.
Step 5. The user executes disinvite p/Louis p/David …
to remove participant(s) from the current activity. The disinvite
command calls Activity#disinvite()
which then modifies the activityList
and is stored in the ActivityBook
.
The sequence diagram for the disinvite operation is omitted as it is similar to the invite operation. |
The following activity diagram summarizes what happens when a user executes an invite command:
The activity diagram for the disinvite command is omitted as it is similar to the invite operation. |
Design Considerations
Aspect: How invite & disinvite executes
-
Alternative 1 (current choice): Contextual based invite/disinvite based on current viewed activity.
-
Pros: More user-friendly. User does not have to keep specifying which activity to invite the participants to each time an invite command is made.
-
Cons: Harder to implement. Have to consider which activity to invite the participants to based on the current viewed activity.
-
-
Alternative 2: Invite/disinvite based on user specifying the activity number.
-
Pros: Easy to implement.
-
Cons: Have to keep retyping activity number if multiple invites/disinvites are needed.
-
Aspect: Data structure to support the invite/disinvite commands
-
Alternative 1 (current choice): Use a list to store the participant’s ID in the activity instead of participant’s name.
-
Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project.
-
Cons: Have to map participant’s ID to participant’s name. Hard to search for participant’s specific ID when given name.
-
-
Alternative 2: Use list to store participants instead of ID
-
Pros: Easy to implement. Reuse what is already in the codebase and we do not need to create additional Unique ID key for each participant to identify them.
-
Cons: Might create duplicate person object when reading from multiple json files if not implemented properly.
-
Delete feature
Implementation
The delete mechanism is facilitated by AddressBook
, ActivityBook
, as well as Activity
.
The items that will be deleted can be contact/activity/expense depending on your current display.
Given below is an example usage scenario and how the delete mechanism behaves at each step.
Step 1. The user launches the application for the first time. SplitWiser
will be initialized with the initial address book and activity book state.
Step 2. The user executes list c/
command to display list contacts screen.
Step 3. The user executes delete 1
to delete the contact at the first index, he/she will be deleted if he/she is not involved in any activity.
Step 4. The user executes list a/
to display list activities screen.
Step 5. The user executes delete 1
again, but this time the activity at the first index will be deleted instead.
Step 6. The user views an activity at the second index using view a/2
Step 7. The user executes delete 1
again, but this time the expense at the first index will be soft deleted instead.
The following activity diagram summarizes what happens when a user executes a delete command for deletion of activity:
The activity diagram for deletion of expense and contact are omitted as they are similar to the deletion of activity. |
Design Considerations
Aspect: How delete executes
-
Alternative 1 (current choice): Contextual based delete of contact/activity/expense based on current displayed screen.
-
Pros: More user-friendly. User does not have to keep specifying what field to delete.
-
Cons: Harder to implement.
-
-
Alternative 2: Delete based on user specifying which field to delete.
-
Pros: Easy to implement.
-
Cons: Have to keep retyping the field for deletion which is inconvenient.
-