PROJECT: Calgo

Overview

This portfolio page highlights some of my contributions to Calgo - a Software Engineering project developed in my second year of undergraduate studies in the National University of Singapore.

About the Team

We are 5 Year 2 Computer Science undergraduates reading CS2103T: Software Engineering.

About the Project

Calgo is an all-in-one personal meal tracking assistant which seeks to encourage a healthy lifestyle among its users. It allows users to not only have a convenient nutritional record of all their favourite food entries, but also track, monitor, and plan their food consumption. Moreover, the team has come up with a plethora of user-centric features to make Calgo well-suited to provide users with both convenience and utility.

My team was tasked with morphing an existing Address Book Level 3 (AB3) project into a new product via Brownfield software development. We were therefore required to use the existing AB3 project as Calgo’s project foundation, to create a desktop application supporting the Command Line Interface. This was to target users who prefer typing but also enjoy the benefits of a Graphical User Interface. With all of us being food lovers and realising a greater societal need for healthy eating, Calgo was born.

Summary of contributions

  • Major enhancement: I implemented the generation of useful statistics and key insights via the report command.

    • What it does: The feature provides the user with a statistical summary of the food he/she has consumed on a given day. It also generates personalised insights on how the user can improve his/her eating habits and whether his/her favourite food item should continue to be part of the diet.

    • Justification: The feature improves Calgo significantly because a user can now go beyond just tracking his/her daily meal consumption. The user can now obtain insights on how to improve their eating habits and find out the food that contributes the most to their daily calorie count. They also no longer have to spend lots of time calculating the nutritional content they consumed in a day because the statistics section does that for them instantly. This makes Calgo much more than a meal tracker. It helps the user build a healthy lifestyle through eating.

    • Highlights: This enhancement requires an in-depth understanding of the Logic and Model components' architecture and a good understanding of String formatting. It also makes use of a sophisticated sorting mechanism to decide what the favourite food of the user is in the past week.

  • Major enhancement: I also implemented the goal command.

    • What it does: The feature helps the user to set a daily calorie goal. This goal is also reflected in Calgo’s GUI, so that the user is always reminded of how many calories he/she is left with whenever they consume food.

    • Justification: Our target user is health-conscious and wants to build a healthy lifestyle. As that is a vague goal, it often is hard to achieve. That is why the goal command is created, to help the user set clear objectives for each day and chunk their big long-term goal of eating healthily into smaller daily goals. This allows them to see noticeable progress too and is motivating. The goal is also used to generate personalised insights in the abovementioned report command.

    • Highlights: For this enhancement, I worked on the front-end, back-end logic, storage of the goal and unit testing as well. This required a deep understanding of all aspects of the project.

  • Minor enhancement: I helped in the redesigning of the GUI by adding the Goal Displays, Remaining Calorie Count Display, creating labels and helping Janice with the graph feature.

  • Code contributed: You can view my functional code and test code contributions to Calgo here.

  • Other contributions:

    • Project management:

      • As the in-charge of Deadlines and Deliverables, I ensured the team was on task and was putting in consistent effort. I also managed all releases v1.1 - v1.4 (4 releases) on GitHub. 1.

      • I maintained the team’s GitHub issue tracker and set up project dashboards and ensured everybody was assigned at least one user story to work on. Furthermore, the user stories were split into multiple milestones to ensure we worked incrementally. 2.

      • Contributed to product ideation, brainstorming key features and ensuring that everyone has equal responsibilities.

    • Team Documentation:

      • Wrote the sections for clear, report and goal commands in Calgo’s User Guide. #161, #169, #171, #288.

      • Wrote sections for Generating statistics and insights, setting daily calorie goals for Developer Guide. #161, #292, #298.

      • Vetted through User Guide and Developer Guide. #307.

      • Refined Calgo’s team pages to be more user-centric (especially README.adoc). #133, #161, #242, #277, #281, #283, #292, #298,

    • Beyond the team:

      • Peer testing and bug reporting: #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12, #13, #14, #15.

      • Providing consistent feedback to peer projects on how to enhace their features. For instance, providing advice to Team F11-3 during tutorials and after the practice demo round.

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.

clear : Clearing all entries

(by Vineeth)

If you want to clear all the Food entries currently stored in your Food Record, this command will be useful to you.

The data in your Consumption Record and Graph Display will not be affected from executing the clear command.
To cater to fast typists who are more likely to make typing mistakes, Calgo will still execute this command even if there are other parameters or words that are typed after clear.

Format: clear

Example:

Suppose that you want to drastically improve your diet. You decide to take a look at all of your Food entries currently in the Food Record but realise none of them fit into your new diet. To avoid the hassle of deleting each Food entry one by one, you decide to clear them. This is what you need to do:

ClearCommandBefore

First, type clear and then press enter, as shown in the above diagram.

ClearCommandAfter

Upon entering the command, all your Food entries in the Food Record will be deleted. This will result in an empty Food Record, as shown above. As mentioned previously, your data in the Consumption Record and Graph Display is left unchanged.

report : Generating key statistics and insights

(by Vineeth)

Why stop at keeping track of your meals? Go a step further and use your past consumption patterns to learn how to improve your eating habits. Moreover, won’t it be convenient if you can automatically generate tips on how to improve? This is exactly what the report command can help you with!

Given a date, the report command analyses your consumption pattern in that day to generate relevant statistics and helpful insights for improving your diet. You no longer have to tediously calculate the total amount of calories you consumed in a day. Calgo does it for you, instantly!

The document generated by the report command is stored in the data/reports folder. This document is named after the given date in this format: yyyy-mm-dd_report.txt. For instance, if you generate a report on 27th of April 2020, the generated document is 2020-04-27_report.txt.
To generate more insightful suggestions, do set a daily calorie goal before generating the report. To learn how to do that, check out the goal command here.

Refer to the list below for the various types of insights that you can easily obtain from the report command.

  • All Food consumed on the given date. For each Food entry, the following information will be included:

    • The name of the Food.

    • Quantity consumed. For instance, 1.5 portions.

    • Number of calories consumed.

  • The total number of calories consumed in that day.

  • The total number of grams of protein, carbohydrate and fat consumed on that day.

  • Insights on whether you have achieved your goal.

  • Insights on what your favourite Food is and whether it should continue to be in your diet.

Format: report d/DATE

When entering the report command, do note there is a default behaviour for the DATE prefix. If you do not provide the date, or if its Prefix does not have a value, Calgo will by default take it that you intend to generate a report based on today’s date.

Example:

Let’s suppose you had a buffet on 27th of April 2020 and you managed to nom lots of exciting Food into your Consumption Record. It is now the end of the day and you want to look back and find out how you fared. This is what you can do:

ReportCommandBefore

First, type report d/2020-04-27 and press enter, as shown above.

SampleReport

Second, go to the data/reports folder and open 2020-04-27_report.txt. You will see a report that looks similar to the one in the above screenshot.

The following steps breakdown what information is included in each section of the report.

ReportHeader

The first section is the Report Header, which states the date of your consumption pattern that is being analysed in the report. In this case, your food consumption pattern on the 27th of April 2020 is analysed in the displayed report screenshot.

ReportGoalInfo

The second section is Your Goal Information. This section reminds you of the daily calorie goal that you have set for yourself.

ReportFoodwiseStatistics

The third section is Food-wise Statistics. As the name suggests, this section provides you with relevant statistics for every Food entry in your Consumption Record of the given day. In this case, you can see a variety of Food entries that you have tracked from your buffet experience. For each Food entry, the report displays the name of the Food, the total number of portions you consumed and the total amount of calories from that Food. You can use this information to realise what Food you may be over-consuming.

ReportAggregateStatistics

The fourth section is Aggregate Statistics, which shows you the total amount of calories, protein, carbohydrates and fat that you have consumed on the given day. This section could be particularly helpful if you are interested in tracking your total nutritional intake each day.

ReportInsights

The fifth section is called Insights for You. In this section, Calgo uses your daily calorie goal to explain how close you were to achieving it. For you to continually improve your eating habits, Calgo, like any other friend, pushes you with motivating messages and congratulates you if you achieved the goal. In this case, as you exceeded the daily calorie goal by 959 calories, Calgo provides you with some reassurance that you can do better the next day to ensure that you do not give up.

ReportSuggestions

The penultimate section is Suggestions for You. In this section, Calgo analyses your Consumption Record of the past week from the given date to find out what you can do to improve your eating habits. Calgo does this by using a mix of your ratings and quantity consumed of each Food to intelligently infer what your favourite Food is. It then analyses if you can continue to keep your favourite Food in the past week in your diet based on your daily calorie goal. Over time, through Calgo’s smart suggestions, you will eventually have a diet consisting of your favourite Food entries that are compatible with your goal. How awesome is that!

ReportFooter

The final section is the Report Footer, which informs you that the report has concluded. This is the part where you realise that Calgo provides you with so many key insights in such a neatly organised and compact document.

goal : Setting a daily calorie target

(by Vineeth)

A healthy lifestyle is not achieved overnight. Calgo understands the importance of keeping the end in mind with regards to achieving your healthy lifestyle. Thus, to motivate you to put in consistent effort, you can set daily calorie goals for yourself using the goal command.

Here are some key pointers:

  • The goal that you set will be used to generate insights in your consumption report. For more information related to that, you check out the report command here.

  • After setting a daily calorie goal, you can still change it whenever you want to. All Calgo insights will subsequently update so that they are based on your most current goal.

Acceptable values are positive integers, ranging from 1 to 99999.

Format: goal GOAL

Example:

Let’s suppose you are a young adult who is trying to lose weight because your favourite jeans have become too tight. You search online for the ideal number of calorie you should consume daily to lose weight. A credible online source states it should be 1900 calories. Now, you want to reflect that daily calorie goal in Calgo. You can do that by following this simple step:

GoalCommandBefore

Type in goal 1900 and press enter, as shown above.

GoalCommandAfter

As you can see, the Daily Goal Display has updated to reflect your daily calorie goal. You can now track your meals and get immediate updates on the remaining amount of calories you have to consume for that day to achieve your goal.

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.

Generating consumption statistics and insights report

(by Vineeth)

This feature allows a user to automatically generate a report that contains statistics and personalised insights based on his or her food consumption pattern on a given date. Do note that the generated report is a .txt file.

The user can invoke this functionality by entering the report command, which follows the following format: report d/DATE.

This section explains:

  • how the report command works and the crucial method it invokes during execution (In the Implementation subsection).

  • the various aspects that were deliberated over when coming up with the design of the statistics and insights report feature (In the Design Considerations subsection).

  • a summary that shows a simplified Activity Diagram that captures the essential logic in the execution of the report command (In the Summary subsection).

Before moving on to learn how the feature works, if you want to see what the report includes, you can refer to our User Guide.

Implementation

The specified feature is facilitated by a ReportGenerator object. If you are interested in how ReportGenerator fits into the architecture of Calgo, refer to this section.

To learn how the report command works, the most important method that you need to know is the generateReport() method from the ReportGenerator class.

Refer to the sequence diagram below to understand the top-level execution of the generateReport() operation after the user enters a valid report command.

ReportFeatureSequenceDiagram
Figure 1. Sequence Diagram for report command: generating 2020-03-27_report.txt
The lifelines for the ReportCommandParser object, ReportCommand object, ReportGenerator object should end at their destroy markers (X) but due to a limitation of PlantUML, the lifelines reach the end of diagram.

From the above diagram, creating a report for the consumption patterns on 27th of March 2020 involves the following steps:

Step 1: User inputs report d/2020-03-27 to generate the insights report based on food consumption of the abovementioned date.

Step 2: This input is saved as a String and passed into the LogicManager.

Step 3: The String input is parsed by CalgoParser, which removes the "d/" Prefix and sends the date input to ReportCommandParser.

Step 4: Once the ReportCommandParser checks that the given date is valid, it creates a ReportCommand object and returns it to LogicManager.

Step 5: LogicManager then executes the ReportCommand.

Step 6: From Model, ReportCommand retrieves the required objects to construct an instance of ReportGenerator.

Step 7: With the relevant objects retrieved from Steps 6, ReportCommand constructs a ReportGenerator object.

Step 8: Using the ReportGenerator object, ReportCommand invokes the crucial method generateInsights(), which prints neatly organised sections of analysed data based on the DailyFoodLog of the input date. For the section that gives insights related to the user’s favourite Food, the past seven days of DailyFoodLog objects are analysed.

Step 9: This newly generated report is saved in the data/reports folder. If the report is successfully generated, the CommandResult is true. Otherwise, it is false. This CommandResult object is finally returned to LogicManager, to signify the end of the command and GUI shows a result message to the user.

Design considerations

Many of the design considerations made for report command are similar to that of the export command. You can check out the similar design considerations over here.

In addition to those design considerations, the following consideration is specific to the functionality of the report command.

Aspect: How many days of past data should be used to analyse user’s favourite Food for the suggestions section of the report.
  • Alternative 1 (current choice): Analyse past seven days of consumption data

    • Pros: This implementation is more efficient as it does not have to churn out all existing consumption data produced by the user so far.

    • Cons: The reliability of the suggestions may be impacted due to certain special events such as buffet celebrations, in which the user may consume Food that he or she does not usually eat.

  • Alternative 2: Analyse all data

    • Pros: The insights will be much more reliable and more tolerant of outlier data points.

    • Cons: The efficiency of the report command gets worse over time and may cause dissatisfaction to the user.

Summary

The following activity diagram summarizes what happens when user executes a report d/DATE command with a correctly formatted date:

ReportActivityDiagram
Figure 2. Activity Diagram for Report command

You can check out this code snippet to see how the ReportCommand object determines if there are no Food entries present in the given date:

// if there is no food consumed on the given date, do not execute command
if (!model.hasLogWithSameDate(queryDate) || model.getLogByDate(queryDate).getFoods().size() == 0) {
   throw new CommandException(MESSAGE_REPORT_FAILURE + "\n" + String.format(NO_SUCH_DATE, queryDate))
}

Setting daily calorie goals for motivation

(by Vineeth)

This feature helps a user chunk his or her long term goal of developing a healthy lifestyle into smaller daily goals. Psychologically, this helps to motivate them as the perceived difficulty of achieving the long term goal reduces.

The user can set a daily calorie goal with the goal command, which follows the following format: goal GOAL.

This section addresses how the goal command works.

Implementation

In addition to the GoalCommandParser, the goal command relies heavily on the DailyGoal class, which is part of the Model component. Refer to the Model component diagram here.

To address the issue where a user does not want to set up a daily calorie goal, Calgo places a DUMMY_VALUE of 0 calories, as shown in the code snippet below, from DailyGoal class. To cater to a wide range of users, it also has a broad range of acceptable values, ranging from 1 to 99999. However, to guide users towards a healthy lifestyle, the App does display a warning message whenever a user sets a goal below the MINIMUM_HEALTHY_CALORIES.

    // Values used for GoalCommandParser when parsing user inputted goals.
    public static final int MINIMUM_HEALTHY_CALORIES = 1200;

    public static final int MINIMUM_ACCEPTABLE_CALORIES = 1;

    public static final int MAXIMUM_ACCEPTABLE_CALORIES = 99999;

    // Default value, when user does not input a goal.
    public static final int DUMMY_VALUE = 0;

Refer to the sequence diagram below to understand how a goal command is executed. .Sequence Diagram for goal command: updating daily calorie goal to 2000 calories.

GoalSequenceDiagram
The lifelines of the GoalCommandParser object, GoalCommand object and DailyGoal object should end at their destroy markers (X) but due to a limitation of PlantUML, the lifelines reach the end of diagram.

The following steps explain the sequence diagram:

Step 1: User inputs goal 2000 to update his or her goal to 2000 calories.

Step 2: This input is saved as a String and passed into the LogicManager.

Step 3: The String input is parsed by CalgoParser, which sends the goal value input to GoalCommandParser.

Step 4: Once the GoalCommandParser checks that the given value is valid, it converts the input to an Integer and creates a GoalCommand object and returns it to LogicManager.

Step 5: LogicManager then executes the GoalCommand, which in turn invokes updateDailyGoal method of Model.

Step 6: In Model, the updateDailyGoal method is a static method that generates a new DailyGoal object with the corresponding input. This DailyGoal object is returned to Model , which replaces the existing DailyGoal attribute of the ModelManager with the newly generated DailyGoal object.

Design Considerations

Aspect: Type of user input data that is required for goal command
  • Alternative 1 (current choice): Use a simple goal feature that accepts the user’s inputted value.

    • Pros:

      • The user is not daunted by the large amount of information he or she needs to provide to set a goal.

      • The user will not feel paranoid as Calgo does not ask for personal data such as height, weight, gender and age.

    • Cons:

      • The goal may not be effective unless the user diligently checks online for a appropriate goal and then enters it into Calgo.

  • Alternative 2: Use a scientific method to calculate the basal metabolic rate of the user.

    • Pros:

      • The goal is very effective because it matches their body type.

    • Cons:

      • A lot of data is required to be inputted by the user.

      • May cause users to avoid setting goals because of the large amount of personal data they need to store in Calgo.

      • User feeling uncomfortable about setting a goal will also affect effectiveness of report command.

Summary

In essence, the goal command is a fun feature that is used to motivate the user and generate specific insights if the user were to invoke the report command after setting a daily calorie goal.

Refer to the Activity Diagram below for a visual summary of the logic behind the execution of the goal command.

GoalActivityDiagram
Figure 3. Activity Diagram for goal command.