About the Project

MoneyGoWhere is a finance application built by my team and I as part of a Software Engineering Project. It was morphed from a basic command line interface Address Book. MoneyGoWhere is a personal finance application targeted at students at the National University of Singapore (NUS). It is designed to help students to keep track of all their spending and their related information such as date, cost and tags. Notable features include allowing users to set budget goals, view statistics, set reminders for bills and export their data to a .csv file.

My Role

My role was to implement the statistics and graph features. The following sections will illustrate these features in greater detail.

Below are a few icons and formatting which will be used in this document.

Important information that should be noted.
Tips that can help you better navigate the application.

test: Command to be executed or a component, class or object in the architecture of the application.

Additional useful information for this section.

Summary of contributions

This section shows a summary of contributions I have made for the project.

  • Major enhancement: I implemented the statistics feature.

    • What it does: It allows the user to view their spending in the form of a pie-chart which organises the user’s expenditure based on tags.

    • Justification: This feature enhances the product significantly as it enables users to view their spending in the form of figures which is more reader-friendly. Furthermore, it allows users to be more informed of their spending habits as they are now aware of where they have spent most of their money on, enabling them to reflect on their spending habits.

    • Highlights: This enhancement required an in-depth understanding of the software architecture as it involves multiple components of the application.

  • Minor enhancement: I implemented the graph feature.

    • What it does: It organises the user’s expenditure based on date, allowing users to view their daily expenditure based on a date range provided.

    • Justification: It enables users to view how much they spend daily and also enable them to analyze trends in their spending amount over a particular period of time. This helps them to better analyze their spending habits.

    • Highlights: This enhancement also required an in-depth understanding of the software architecture as it involves multple components of the application.

  • Code contributed: [Collated code]

  • Other contributions:

    • Project management:

      • Helped track issues on the team repository using labels, milestones and project card

    • Enhancements to existing features:

      • Refactored and modified existing class Address to Cost to fit the needs of our application (Pull requests #61, #67, #71)

    • Documentation:

      • Vetted and formatted the entire User Guide after individual contributions by team members (Pull request #101)

      • Reviewed team member’s documentations (Pull requests #80, #85, #98)

      • Updated Quick Start section and created a set of symbols/legends for User Guide (Pull requests #50, #101)

      • Collated and updated profiles for all members of the team (Pull request #7)

      • Updated Setting Up, Documentation, Testing and DevOps sections of Developer Guide (Pull request #244)

    • Community:

      • PRs reviewed with non-trivial review comments (Pull requests #62, #70, #81)

      • Conducted manual testing, reported bugs and offered suggestions for our team (Examples: 1, 2, 3)

      • Conducted manual testing, reported bugs and offered suggestions for other teams in the class (Examples: 1, 2, 3)

Contributions to the User Guide

Given below are sections I contributed to the User Guide for the Statistics feature and Graph feature. They showcase my ability to write documentation targeting end-users.

Generating statistics : stats

Organises the spending based on tags. A pie chart is generated, with each sector representing the total amount of money spent on a tag. This enables users to be more informed of their spending habits as they are now aware of where they have spent most of their money on. An example is shown below.

stats
Figure 1. Output of stats d/21/10/2019 d/25/10/2019

Format: stats d/DATE_START d/DATE_END

  • Generates statistics for all spending that fall between and including the DATE_START and DATE_END specified by the user.

  • If no DATE_START and DATE_END parameters are specified, the statistics generated will be based on the whole list of spending.

  • Only spending that have at least a tag will be considered.

  • Only the top few tags which incurred a more significant amount of money will be displayed.

Spending with multiple tags will be counted more than once in total as the statistics seek to show the user which tag they have spent the most money on.
DATE_START must be earlier or the same as DATE_END.
Date range can be input in the following ways:
d/DATE_START d/DATE_END
d/DATE_START to DATE_END
d/DATE_START - DATE_END
The statistics panel will update every time the spending list displayed changes. For example, when a new spending with a tag is added, the statistics panel will update the pie chart to show the statistics for all spending, including the new spending.
The statistics panel will update with the currency set.

Examples:

  • stats: Generates statistics for all spending.

  • stats d/20/10/2019 d/25/10/2019: Generates statistics for spending between and including 20/10/2019 and 25/10/2019.

Expected Output:

Statistics is shown.

Generating a graph : graph

Organises the spending based on date. A line graph is generated, with each point representing the total amount of money spent on a particular date. This enables users to analyze trends in their spending amount over a particular period of time. An example is shown below.

graph
Figure 2. Output of graph d/21/10/2019 d/25/10/2019

Format: graph d/DATE_START d/DATE_END

  • Generates a graph for all spending that fall between and including the DATE_START and DATE_END specified by the user.

  • If no DATE_START and DATE_END parameters are specified, the statistics generated will be based on the whole list of spending.

  • Only dates that have at least a spending will be recorded in the graph.

DATE_START must be earlier or the same as DATE_END.
Date range can be input in the following ways:
d/DATE_START d/DATE_END
d/DATE_START to DATE_END
d/DATE_START - DATE_END
Hovering the mouse over a point displays the date and total amount of money spent (to the nearest dollar) on that date.
The graph panel will update every time the spending list displayed changes. For example, when a new spending is added, the graph panel will update and generate a graph for all spending, including the new spending.
The graph panel will update with the currency set.

Examples:

  • graph: Generates a graph for all spending.

  • graph d/20/10/2019 d/25/10/2019: Generates a graph for spending between and including 20/10/2019 and 25/10/2019.

Expected Output:

A graph is shown.

Contributions to the Developer Guide

Given below are sections on the implementation of the Statistics feature and Graph feature I have worked on. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

Statistics feature

Current Implementation

For the current statistics feature, there are 2 main commands that the user can execute.

  1. stats - display statistics for all spending

  2. stats d/DATE_START d/DATE_END - display statistics for spending within a date range

The StatsCommandParser differentiates these 2 commands based on whether a valid date range is provided as illustrated in the diagram below.

StatsActivityDiagram
Figure 3. Activity Diagram showing behaviour of StatsCommandParser
  1. If a valid date range is provided in the stats command given by the user, StatsCommand(DATE_START, DATE_END) with the respective date parameters is created. The command will execute based on this date range.

  2. If no date range is provided by the user, StatsCommand() is created, which will execute the command based on the whole date range in the list.

  3. Else, if the parameters are invalid, a ParseException is thrown and the application waits for a new user input.

The implementation of the Statistics feature can be split into 2 phases, preparation and execution. Given below is an explanation of how the Statistics mechanism behaves at each phase.

Preparation

During the preparation phase, the program parses the command for Statistics and verifies the arguments. The following sequence diagram shows how stats command works during the preparation phase.

StatsSequenceDiagram
Figure 4. Sequence Diagram demonstrating the preparation stage of Statistics feature
The lifeline for StatsCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
  1. User first enters a stats command.

  2. SpendingBookParser will parse and identify the command as a StatsCommand and pass on the argument to StatsCommandParser.

  3. If no arguments were provided by the user, StatsCommand#StatsCommand() is called to create a StatsCommand with no parameters. Otherwise, StatsCommandParser will verify whether the arguments provided were valid.

    1. If they are valid, StatsCommand#StatsCommand(DATE_START, DATE_END) is called to create a StatsCommand with the specified parameters.

    2. Else, a ParseException will be thrown and an error message will be shown to the user.

  4. StatsCommand is returned to LogicManager which then calls StatsCommand#execute().

  5. Model#updateFilteredSpendingList(predicate) is subsequently called to update the list.

Execution

In the execution phase, the program processes and retrieves the data to be displayed and finally displaying it. Below is the UML sequence diagram and a step-by-step explanation.

StatsDataSequenceDiagram
Figure 5. Sequence Diagram demonstrating the execution stage of Statistics feature
  1. Upon checking that the boolean isShowStats = true, the MainWindow calls LogicManager#getStatsData().

  2. LogicManager then gets the filtered list by calling Model#getStatsList, which returns an unmodifiable ObservableList, containing only spending within the specified date range.

  3. LogicManager#getStatsData() then processes the spending and organise the data into a LinkedHashMap<String, Double> where the key value pairs represents tag and cost respectively.

  4. Finally, the statsData is returned to the MainWindow. The data will be displayed on the Ui through StatsPanel#loadData(statsData) call.

Design Considerations

Aspect Alternative 1 (Current choice) Alternative 2

Visual Representation of Statistics

Represent data in the form of a pie chart.
Pros: Limits the number of tags to the tags that are the most significant. Will not encounter any errors in the event there is a large number of tags.
Cons: Unable to display the data of other tags that are less significant.

Represent data in the form of a table.
Pros: Able to view the data of more tags.
Cons: Less reader-friendly option due to the large amount of data. Data is not summarized easily for the user to analyze his spending habits.

Graph feature

Current Implementation

For the current graph feature, there are 2 main commands that the user can execute.

  1. graph - generates graph for all spending

  2. graph d/DATE_START d/DATE_END - generates graph for spending within a date range

The GraphCommandParser differentiates these 2 commands based on whether a valid date range is provided as illustrated in the diagram below.

GraphActivityDiagram
Figure 6. Activity Diagram showing behaviour of GraphCommandParser
  1. If a valid date range is provided in the graph command given by the user, GraphCommand(DATE_START, DATE_END) with the respective date parameters is created. The command will execute based on this date range.

  2. If no date range is provided by the user, GraphCommand() is created, which will execute the command based on the whole date range in the list.

  3. Else, if the parameters are invalid, a ParseException is thrown and the application waits for a new user input.

The implementation of the Graph feature can be split into 2 phases, preparation and execution. Given below is an explanation of how the Graph mechanism behaves at each phase.

Preparation

During the preparation phase, the program parses the command for Graph and verifies the arguments. The following sequence diagram shows how graph command works during the preparation phase.

GraphSequenceDiagram
Figure 7. Sequence Diagram demonstrating the preparation stage of Graph feature
The lifeline for GraphCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
  1. User first enters a graph command.

  2. SpendingBookParser will parse and identify the command as a GraphCommand and pass on the argument to GraphCommandParser.

  3. If no arguments were provided by the user, GraphCommand#GraphCommand() is called to create a GraphCommand with no parameters. Otherwise, GraphCommandParser will verify whether the arguments provided were valid.

    1. If they are valid, GraphCommand#GraphCommand(DATE_START, DATE_END) is called to create a GraphCommand with the specified parameters.

    2. Else, a ParseException will be thrown and an error message will be shown to the user.

  4. GraphCommand is returned to LogicManager which then calls GraphCommand#execute().

  5. Model#updateFilteredSpendingList(predicate) is subsequently called to update the list.

Execution

In the execution phase, the program processes and retrieves the data to be displayed and finally displaying it. Below is the UML sequence diagram and a step-by-step explanation.

GraphDataSequenceDiagram
Figure 8. Sequence Diagram demonstrating the execution stage of Graph feature
  1. Upon checking that the boolean isShowGraph = true, the MainWindow calls LogicManager#getGraphData().

  2. LogicManager then gets the filtered list by calling Model#getStatsList, which returns an unmodifiable ObservableList, containing only spending within the specified date range.

  3. LogicManager#getGraphData() then processes the spending and organise the data into a LinkedHashMap<String, Double> where the key value pairs represents date and cost respectively.

  4. Finally, the graphData is returned to the MainWindow. The data will be displayed on the Ui through GraphPanel#loadData(graphData) call.

Design Considerations

Aspect Alternative 1 (Current choice) Alternative 2

Whether to merge Graph and Statistics features into one command

Distinct commands for Graph and Statistics features.
Pros: Distinct commands with similar parameters make it easy for the user to remember and use. One feature could be easily modified without affecting the other feature.
Cons: Code duplication due to similarity of implementation.

Merge Graph and Statistics features into one command.
Pros: Reduces code duplication due to similarity of implementation.
Cons: Another parameter needed for user to indicate the mode he prefers to view his statistics. Difficult to modify one feature without needing to modify the other as well.