1. Introduction
This portfolio serves to showcase my roles and contributions to the team project THRIFT. This project was part of the requirements of a year two software engineering module, CS2103T, that I had taken as an undergraduate in NUS.
In this project, I was the team lead and was primarily in charge of leading the team towards our end-product.
My team members were: Lee Bo Qiang
(User Experience Developer), Melvin Ang
(Software Architect), Lye Jian Wen
(Quality Assurance Manager) and Kenson Oen
(Process Analyst). We all had important and major roles to play in order to ensure that THRIFT is successful.
1.1 Project: THRIFT
THRIFT is a finance tracker desktop application targeting money-conscious NUS students who wish to keep their spending in check. It allows its users to set a budget for each month and track incoming and outgoing transactions. This would remind the user not to overspend as they will constantly see their remaining balance for that month. The following image is how THRIFT looks like:
1.2 Background of THRIFT
THRIFT is morphed from the original AddressBook-Level3 application which allows users to add contacts to create a personalised list. My team and I have since transformed the application to better suit our purpose.
1.3 Understanding this document
There are various text styles used in this portfolio and its usages are explained below:
This symbol denotes information that you may want to take note of when using the application. |
The following text styles are only applicable to the section on the Developer Guide:
currentMonth
|
Text with grey highlight (called a mark-up) indicates that it is a method/variable name. |
Expense
|
Bold text with mark-up indicates a class/package name. |
2. Summary of Contributions
This section provides a summary on the various contributions that I have made to THRIFT.
2.1 Enhancements made
Major enhancements:
-
Added the ability to add transactions into the transaction list.
-
What it does: The add_expense and add_income commands allow the user to track their incoming and outgoing transactions.
-
Justification: It is a core feature to be able to add transactions into THRIFT.
-
Highlights: I had to modify the original AddressBook-Level3 codebase to add a transaction instead of a person. Additionally, the user is able to optionally annotate each transaction with a
Remark
andTag
.
-
-
Added the ability to set the budget for a specified month.
-
What it does: The budget command allows the user to set their budget for a particular month.
-
Justification: With a budget set, the user can see if they are within their spending limit for the month.
-
Highlights: I had enhanced THRIFT to show the updated balance whenever the user changes their budget.
-
Minor enhancements:
-
Modified the THRIFT interface to display transactions instead of people.
-
Justification: THRIFT deals with transactions and not people objects, there is no longer the need to maintain people objects.
-
Highlights: I coloured incomes as green and expenses as red to improve the user experience by making the displayed information intuitive.
-
2.2 Code contributed
Please follow these links to see a sample of my code: [Commits] [Pull requests] [RepoSense Code Contribution Dashboard]
2.3 Other contributions
-
Project management:
-
There were a total of 5 releases, from version 1.0 to 1.4. I managed every release on GitHub.
-
-
Enhancement to existing features:
-
Refactored the original AddressBook-Level3 codebase to fit our requirements. (Pull request #62)
-
Updated the original delete command to require a prefix i/INDEX to specify which transaction the user wishes to delete. This makes the delete command syntax consistent with the update command. (Pull request #104)
-
Updated the original find command to search for the specified keyword(s) in a transaction’s
Remark
as well asDescription
. (Pull request #163)
-
-
Documentation:
-
Updated the architecture diagrams in the original developer guide to suit the context of
THRIFT
. (Pull request #169) -
Updated the user guide to acknowledge the original codebase.
-
-
Community:
3. Contributions to the User Guide
The following section illustrates my ability in writing documentation to guide end-users on using the various features of THRIFT.
{Start of extract}
Setting monthly budget: budget
Ready to save? One of the key steps in saving money is to clearly define your monthly budget. With a budget set, you will always see your remaining balance! This will definitely encourage you to spend wisely and to keep your spending in check. Take the first step in saving by setting your budget for each month in THRIFT!
It is not compulsory to set a budget for each month and you can use THRIFT normally without setting budgets. |
Command syntax:
budget v/VALUE d/MONTH/YEAR
Example usage:
You wish to set your budget for the month October 2019 as $2000:
-
Your current budget for the month October 2019 is $0.
-
You type: budget v/2000 d/10/2019 in the Command Box and press Enter.
-
You should see in the Result Box that your budget for October 2019 has been set to $2000.
If you are changing your budget for the current displayed month, you should see the changes on the GUI immediately.
{End of extract}
4. Contributions to the Developer Guide
The following section illustrates my ability in writing documentation to provide developers insights on the design of the application. It also showcases the technical depth of my contributions to THRIFT.
{Start of extract}
Adding transactions
We allow users to add Expense
/Income
transactions into THRIFT
which enables record-keeping. This section will show how we handle such
requests from the user at the back-end.
Implementation
We store every single Transaction
added by the user into an ObservableList<Transaction>
, which is a list object in TransactionList
. We used an ObservableList
because whenever there are changes to the list, any other component
of THRIFT
using it will automatically reflect its changes.
We implemented adding a Transaction
through the following commands: add_expense/add_income. This process leverages on polymorphism: Expense
and Income
are both subclasses of the abstract class Transaction
.
Each Transaction
contains the following mandatory fields: Description
, TransactionDate
and Value
; as well as optional fields: Remark
,
and Set<Tag>
. The following class diagram depicts this relation:
Because of this polymorphism relation, many of the driver functions in THRIFT
simply references Transaction
and it will work for both Expense
and Income
transaction objects. For example, when inserting a new Expense
/Income
, the AddTransactionCommandParser
will determine
which object to initialize. The sequence diagram below shows how adding a Transaction
work in the back-end:
Transaction
is processed with polymorphismExpense
and Income
are normally instantiated by either ExpenseCommandParser#parse(String args)
or IncomeCommandParser#parse(String args)
, which
attempts to parse the various parameters supplied in args
and return either a Expense
or Income
object. The following conditions will cause a ParseException
to be thrown by the parser:
-
Missing parameters
-
Incorrect syntax (i.e. missing prefix, if it is required)
-
Illegal values in parameters (i.e. special characters and symbols entered for a integer-only field)
-
Multiple occurrences of parameters which only expects a single entry
If the user input is incorrect due to any of the reasons above, the usage syntax will be shown. |
We will demonstrate how a Transaction
is added into THRIFT
and how the back-end handles each step of the process:
Step 1. The user executes add_expense n/Laksa v/3.50 to insert an Expense
with its Description
set to "Laksa"
and its Value
set to "3.50". The TransactionDate
is set to the user’s current system date in the form "dd/mm/yyyy".
The input is now checked and an attempt to parse each parameter occurs:
-
Description
is parsed byAddTransactionCommandParser#parseTransactionDescription(ArgumentMultimap)
-
Value
is parsed byAddTransactionCommandParser#parseTransactionValue(ArgumentMultimap)
-
TransactionDate
is instantiated byAddTransactionCommandParser#parseTransactionDate()
ArgumentMultimap is a class that stores all the parsed parameters taken from the user input.
|
Since the user input is valid, the Expense
is successfully created and inserted into the transaction list.
The transaction list now contains 1 Transaction
object.
Step 2. The user executes add_income n/Bursary v/500 r/Awarded for doing well in school to insert an Income
.
The input is now checked in a similar fashion as in Step 2 except that:
-
Remark
is parsed byAddTransactionCommandParser#parseTransactionRemark(ArgumentMultimap)
Again, since the input is valid, the Income
is successfully added into the transaction list. The transaction list
now contains 2 Transaction
objects.
The following activity diagram summarizes what happens when the user executes a command to add a new Transaction
:
Transaction
into the transaction listDesign considerations
There are many different ways to implement how a transaction is added into THRIFT
. In this section, we will be
justifying why we chose to implement it the way we did.
Aspect: Differentiating between Expense
and Income
-
Alternative 1: (current choice): Introduce a
Transaction
parent class which bothExpense
andIncome
extends from.-
Pros: Introduces polymorphism, easing references to either classes by simply referencing the
Transaction
object. For example, using a singleList<Transaction>
instead of needing 2 separate listsList<Expense>
andList<Income>
. -
Cons: Reduces the readability of the program as polymorphism can be confusing.
-
-
Alternative 2: Keep
Expense
andIncome
classes separate, with each having their own specialized methods.-
Pros: Maintains an intuitive design:
Expense
deducts money andIncome
increases money. -
Cons: Incurs significant overhead and duplicated codes since it is likely that both
Expense
andIncome
will have very similar methods.
-
Alternative 1 was chosen because we want to model it close to the real world: both Expense
and Income
are described
as being a Transaction
.
Aspect: Managing how Value
is stored and handled in Expense
and Income
-
Alternative 1: (current choice): Disallow negative
Value
inExpense
object, only using positive amount for bothExpense
andIncome
-
Pros: Removes the need to implement support for inserting negative
Value
. This is due to howValue
constraints are applied when restoringTHRIFT
data from the data file. -
Cons: Requires the developer to manually negate the
Value
whenever calculations are done with aExpense
object.
-
-
Alternative 2: Allow only negative amount in
Expense
object and only positive amount inIncome
object-
Pros: Calculating the balance becomes trivial - simply sum up the entire
List<Transaction>
. -
Cons: Parsing the user input to allow only a single negative symbol and no other symbols causes an overhead.
-
Alternative 1 was chosen because we want to keep the transaction list clean - only positive integers are stored.
{End of extract}