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 abovementionedreport
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
andgoal
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:
-
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:
First, type clear
and then press enter, as shown in the above diagram.
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.
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:
First, type report d/2020-04-27
and press enter, as shown above.
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.
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.
The second section is Your Goal Information
. This section reminds you of the daily calorie goal that you have set for yourself.
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.
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.
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.
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!
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:
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:
Type in goal 1900
and press enter, as shown above.
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.
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:
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.
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.
goal
command.