Overview
EYLAH is a desktop application specifically programmed for Freshmen staying on NUS Campus. It aims to ease their lives at halls/residential colleges by providing them with an application to split bills easily and help them track their diet. The user interacts with it using a CLI and it is programmed using JAVA 11.
Summary of contributions
-
Major Enhancements:
-
Adding of Height, Weight, Mode, Bmi and Self classes, and their storage components for the Diet Tracker portion of EYLAH (Pull request #109, #109, #157, #312)
-
What it does:
These classes are used to stored user’s metrics and also perform calculations. -
Justification:
The User needs a Health Metrics Tracker to aid his Dieting. -
Highlights:
Implementing Self was rather tricky at first, since I had used static references class attributes, thinking that it would be stored without a Storage. Together with Akhil, we managed to resolve this issue. -
Credits:
My groupmate Akhil, who helped with the correction for some of the bugs in the implementation of the classes. (Akhil’s resolution and refactors - Pull request #318)
-
-
Suggested for the renaming of same sounding class components across both DietTracker and ExpenseSplitter for EYLAH (#Github Discussion)
-
What it does:
Allows the integration of the both Diet Tracker and Expense Splitter seamlessly in the unified EYLAH class. -
Highlights:
I noticed this in my review of my team mate, Shee Xiong’s, initial reorganisation of the code to allow for unification of both components. Upon further research, Java does not support class name aliasing. -
Credits:
I understood more about Java Name Aliasing from here. Shee Xiong, our Team’s Integrations IC, went ahead and implemented it eventually in this following PR: (Pull request #232)
-
-
-
Minor Enhancements:
-
Performed defensive coding for
bmi
,height
, andweight
commands.
(Height, Weight & Bmi - Pull request #351, #378)-
What it does:
bmi
,height
andweight
commands are commands in Diet Tracker, which includes numerical digits and multiple parameters. Common exploits that could break the program was with Integer Overflow values. I combat these errorneous commands by setting limits on their values by checking them through BigDecimal. -
Justification:
Significantly reduces the chances of breaking Diet Tracker and crashing EYLAH.
-
-
Fixed the Calories bug that occurs when Calories are not in the desired range. (Pull request #354)
-
What it does:
Properly validates the user’s Calories input for any of the Diet Tracker Commands which involve Calories. -
Highlights
The original implementation had failed to consider a VALIDATION_REGEX for the Calories String itself, since Calories was built using a long instead of directly from a String. Another issue was that you could exceed in the input long for Calories which would crash the program also. This was circumvented using BigInteger.
-
-
-
Code contributed: [Functional Code and Test Code]
-
Other contributions:
-
Project management:
-
In charge of Diet Tracker functionalities for EYLAH.
-
Drew most UML Diagrams for the various Diet Tracker classes and functions for EYLAH.
-
-
Enhancements to existing features:
-
Documentation:
-
Community:
-
Reported bugs and suggestions for other teams in the class (examples: https://github.com/jarrod-bob/ped/issues)
-
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. |
Diet Tracker : diet
Using a Dieting App has never been easier! You can easily achieve the functionalities of a standard Dieting App with Diet Tracker.
Diet Tracker will help you achieve your ideal weight and body mass!
You can store all your food intake everyday and calculate useful information.
Calculating Body Mass Index (BMI) bmi
In this section, you will learn more about the bmi
command, how to use it
and the expected outcome after using the
bmi
command.
Summary of Bmi Command:
bmi
You can calculate your BMI either through an input height and weight or your previously stored Height and Weight.
It will display the following data:
-
BMI value
How to use the Bmi Command:
Format:
bmi [-h HEIGHT] [-w WEIGHT]
Valid Examples:
-
height 172
weight 65
bmi
Change your height and your weight to your current measurements before calculating your BMI. BMI is calculated based off the stored height and weight in this instance. -
height 173.5
bmi -w 59.9
Change your height to your current measurements before calculating you BMI. BMI is calculated based off the stored height and input weight in this instance. -
bmi -h 172 -w 65.5
Calculate BMI based on the input height and weight values.
Expected outcome:
Additional tips
If you are unsure whether you have already input your height and weight, you may |
Storing Height height
In this section, you will learn more about the height
command, how to use it
and the expected outcome after using the
height
command.
Summary of Height Command:
height
You can use this command to save your Height to the Diet Tracker.
How to use the Height Command:
Format:
height HEIGHT
Valid Example:
height 170.2
Expected outcome:
Additional notes and tips
Height in centimetres (cm). Decimal places are accepted. I.e. |
Check your stored height with |
Storing Weight weight
In this section, you will learn more about the weight
command, how to use it
and the expected outcome after using the
weight
command.
Summary of Weight Command:
weight
You can use this command to save your Weight to the Diet Tracker.
How to use the Weight Command:
Format:
weight WEIGHT
Valid Example:
weight 65.7
Expected outcome:
Additional notes and tips
Weight in kilograms (kg). Decimal places are accepted. I.e. |
Check your stored weight with |
Dieting Mode mode
In this section, you will learn more about the mode
command, how to use it
and the expected outcome after using the
mode
command.
Summary of Mode Command:
mode
You can set your desired dieting goal with the different modes that set a limit on your daily
calorie intake. The calorie limits are calculated based on that of an average human. Your daily calories intake status
can be monitored with the list
command.
Switch the dieting mode, based on the following modes:
-
Lose Weight (-l) (2000 calorie limit)
-
Gain Weight (-g) (3000 calorie limit)
-
Maintain (-m) (2500 calorie limit)
How to use the Mode Command:
Format:
mode [-l] [-g] [-m]
Valid Example:
mode -l
You must only input EXACTLY ONE mode per mode command. |
Expected outcome:
Additional notes and tips
The default mode is MAINTAIN if you have not set your mode. |
|
Showing your Metrics metrics
In this section, you will learn more about the metrics
command, how to use it
and the expected outcome after using the
metrics
command.
Summary of Metrics Command:
metrics
You can print out your individual metrics (Height, Weight and Mode) to check them.
It will display the following data:
-
Your height
-
Your weight
-
Your chosen Dieting Mode
How to use the Metrics Command:
Format:
metrics
Valid Example:
metrics
Expected outcome:
Additional notes and tips
Diet Tracker will prompt you if you did not have any previously stored Height, Weight. |
Use this to check whether you have previously stored a Height, a Weight, or have chosen your Dieting Mode already. |
Editing a Food Item edit
In this section, you will learn more about the edit
command, how to use it
and the expected outcome after using the
edit
command.
Summary of Edit Command:
edit
You can edit either the Food name, or the calories of the food at the specified index.
How to use the Edit Command:
Format:
edit -i INDEX [-n NAME] [-c CALORIES]
Valid Example:
edit -i 2 -n Chicken Rice -c 585
Edits the name of the food item at index 2 to be 'Chicken Rice' and the calories to be '585'.
You MUST use list to check the list of items to identify a target to edit. This would ensure that you get the
correct index of the item.
|
Expected outcome:
Additional notes and tips
You can list based on time period or tags to find the item that you want to edit. |
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. |
Diet Tracker feature
The Diet Tracker feature is designed to aid our users in maintaining a healthy lifestyle. The feature comprises of 10 Commands.
-
AddCommand
- Creates a new Food object with its attributes (Name, Calories) and adds it to the FoodBook Storage. -
DeleteCommand
- Deletes the Food specified by the input index from FoodBook Storage. -
ListCommand
- Lists the Foods and its attributes (Name, Calories) for the timeframe specified by users based on their user input. -
EditCommand
- Allows the user to edit an of the Food in Storage. -
HeightCommand
- Allows users to log their Height in centimeters. -
WeightCommand
- Allows users to log their Weight in kilograms. -
BmiCommand
- Calculates the BMI. -
ModeCommand
- Allows users to toggle between different modes of the diet tracker. -
MetricsCommand
- Allows users to check their health metrics, like their Height, Weight and Dieting Mode. '''==== Edit Command
In this section, we will learn more about how the edit
command is implemented.
What is the Edit Command
The edit
command allows users to edit the Name of the Food or the Calories of the Food from the FoodBook via the Index.
The edit
command was implemented as EditCommand
in the diettracker/logic/commands
package.
The edit
command has the following input format:
edit
-i INDEX
[-n NAME]
[-c CALORIES]
|
The following activity diagram illustrates what happens when a user executes the edit
command:
Structure of Edit Command
In this section, you will learn more about the relationships between objects related to the edit
command.
The above class diagram shows the structure of the EditCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in EditCommand
Implementation
The following is a detailed explanation of the operations EditCommand
performs.
-
The
EditCommand#execute(DietModel dietModel)
method is executed and it validates that the specifiedINDEX
to edit is within range. If valid, the item to be edited will be retrieved from Storage using itsIndex
. -
The method
DietModel#getFilteredFoodList() will then be called to retrieve the List of Foods from Storage. `List#get(int Index)
is then invoked which retrieves the specified Food to be edited. -
The method
DietModel#setFood(Food toBeEdited, Food editedFood)
will then be called to replace the Food toBeEdited with the Food editedFood in the List of Foods. -
If successful, a success message will be generated by
CommandResult
and it will be returned with the generated success message. Otherwise, an error message showing the correct command syntax is thrown asCommandException
. -
If the command syntax was valid and Food was edited in FoodBook,
LogicManager
callsFoodBookStorage#saveFoodBook(ReadOnlyFoodBook foodBook)
which saves the new Foods into JSON format after serializing it usingJsonAdaptedFood
.
Sequence Diagram for Edit Command
The following sequence diagram summarizes what happens during the execution of edit
command.
Bmi Command
In this section, we will learn more about how the bmi
command is implemented.
What is the Bmi Command
The bmi
command allows the user to calculate their Body Mass Index (BMI).
The bmi
command was implemented as BmiCommand
in the diettracker/logic/commands
package.
The bmi
command has the following input format:
bmi
[-h HEIGHT]
[-w WEIGHT]
|
The following activity diagram illustrates what happens when a user executes the bmi
command:
Structure of Bmi Command
In this section, you will learn more about the relationships between objects related to the bmi
command.
The above class diagram shows the structure of the BmiCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in BmiCommand
Implementation of Bmi Command
The following is a detailed explanation of the operations BmiCommand
performs. BmiCommand
has two different usages
depending on the user input.
-
The
BmiCommand#execute(Model dietModel)
method is executed and it will return the output of the calculated BMI based on user arguments. -
If successful, a success message will be generated by
CommandResult
and it will be returned with the generated success message. Otherwise, an error message showing the correct command syntax is thrown asCommandException
.
Sequence diagram for Bmi Command
Given below are 2 example usages of BmiCommand
based on different user input.
Usage 1: No Height and Weight input
-
User launches application and enters
Diet
mode. The user then entersbmi
as the command. -
The FoodBook parser validates this command and sets up the
BmiCommandParser
, which checks for the input. -
Since there are no arguments, the
BmiCommandParser
will call the empty constructorBmiCommand()
. -
BmiCommand
would then refer to the internal state of the splitterModel under Self, and retrieve the values stored in Self’s Height and Weight attributes. -
BmiCommand()
will then proceed to calculate the BMI based on the current values of height and weight.
The following is a sample sequence diagram of the BmiCommand
with no additional user input.
There is a need to ensure that there are stored values in Height and Weight attributes in the Self class.
|
Usage 2: With Height and Weight input
-
User launches application and enters
Diet
mode. The user then entersbmi
as the command. -
The FoodBook parser validates this command and sets up the
BmiCommandParser
, which checks for the input. -
Since there are no arguments, the
BmiCommandParser
will call the empty constructorBmiCommand()
. -
BmiCommand
would then refer to the internal state of the splitterModel under Self, and retrieve the values stored in Self’s Height and Weight attributes. -
BmiCommand()
will then proceed to calculate the BMI based on the current values of height and weight.
The following is a sample sequence diagram of the BmiCommand
with additional user input.
Design Considerations
Aspect: How BmiCommand
executes
-
Alternative 1 (current choice): Executes with other without arguments
-
Pros: More flexible use of the Command, better user experience overall.
-
Cons: Harder to implement, as there needs to be multiple BmiCommand constructors.
-
-
Alternative 2: Executes separately with arguments input and without arguments input
-
Pros: Easier to implement, less potential bugs as Command uses a single constructor.
-
Cons: We must ensure that the implementation of each individual command are correct.
-
Aspect: Storage of BMI
-
Alternative 1 (current choice): No splitterStorage of BMI value, simply prints when user requests.
-
Pros: Less memory used; reduces complexity of the Command and objects involved.
-
Cons: Users may want to access it elsewhere from Self.
-
-
Alternative 2: Storage of BMI value in Self class in Model.
-
Pros: Users have access to it anytime.
-
Cons: Coding complexity. '''
==== Height Command
-
In this section, we will learn more about how the height
command is implemented.
What is the Height Command
The height
command allows the user to store their Height into the Diet Tracker.
The height
command was implemented as HeightCommand
in the diettracker/logic/commands
package.
The height
command has the following input format:
height
HEIGHT
|
The following activity diagram illustrates what happens when a user executes the height
command:
Structure of Height Command
In this section, you will learn more about the relationships between objects related to the height
command.
The above class diagram shows the structure of the HeightCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in HeightCommand
Implementation of Height Command
The following is a detailed explanation of the operations HeightCommand
performs.
-
The
HeightCommand#execute(DietModel dietModel)
method is executed and it validates that the specifiedHEIGHT
to store is a valid Height. If valid, the height will be stored in theSelf
class. -
The method
DietModel#setHeight(Height height)
will then be called to set the Height of theSelf
class.Self#setHeight(Height height)
is invoked which makes a call to its internal Height to replace the value stored. -
If successful, a success message will be generated by
CommandResult
and it will be returned with the generated success message. Otherwise, an error message showing the correct command syntax is thrown asCommandException
.
Sequence diagram for Height Command
The following sequence diagram summarizes what happens during the execution of height
command.
Weight Command
In this section, we will learn more about how the weight
command is implemented.
What is the Weight Command
The weight
command allows the user to store their Weight into the Diet Tracker.
The weight
command was implemented as WeightCommand
in the diettracker/logic/commands
package.
The weight
command has the following input format:
weight
WEIGHT
|
The following activity diagram illustrates what happens when a user executes the weight
command:
Structure of Weight Command
In this section, you will learn more about the relationships between objects related to the weight
command.
The above class diagram shows the structure of the WeightCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in WeightCommand
Implementation of Weight Command
The following is a detailed explanation of the operations WeightCommand
performs.
-
The
WeightCommand#execute(DietModel dietModel)
method is executed and it validates that the specifiedWEIGHT
to store is a valid Weight. If valid, the Weight will be stored in theSelf
class. -
The method
DietModel#setWeight(Weight weight)
will then be called to set the Weight of theSelf
class.Self#setWeight(Weight weight)
is invoked which makes a call to its internal Height to replace the value stored. -
If successful, a success message will be generated by
CommandResult
and it will be returned with the generated success message. Otherwise, an error message showing the correct command syntax is thrown asCommandException
.
Sequence diagram for Weight Command
The following sequence diagram summarizes what happens during the execution of weight
command.
Mode Command
In this section, we will learn more about how the mode
command is implemented.
What is the Mode Command
The mode
command allows the user to store their Dieting Mode into the Diet Tracker.
The mode
command was implemented as ModeCommand
in the diettracker/logic/commands
package.
The mode
command has the following input format:
mode
[-l]
[-g]
[-m]
Users must only enter EXACTLY ONE of the given flags for the mode. |
The following activity diagram illustrates what happens when a user executes the mode
command:
Structure of Mode Command
In this section, you will learn more about the relationships between objects related to the mode
command.
The above class diagram shows the structure of the ModeCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in ModeCommand
Implementation of Mode Command
The following is a detailed explanation of the operations ModeCommand performs.
-
The
ModeCommand#execute(DietModel dietModel)
method is executed and it validates that the specifiedMODE
(based on the input flag) to store is a valid flag. If valid, the corresponding mode to the flag will be stored in theSelf
class. -
The method
DietModel#setMode(Mode mode) will then be called to set the Mode of the `Self
class.Self#setMode(Mode mode)
is invoked which makes a call to its internal Mode to replace the value stored. -
If successful, a success message will be generated by
CommandResult
and it will be returned with the generated success message. Otherwise, an error message showing the correct command syntax is thrown asCommandException
.
Sequence diagram for Mode Command
The following sequence diagram summarizes what happens during the execution of mode
command.
Metrics Command
In this section, we will learn more about how the metrics
command is implemented.
What is the Metrics Command
The metrics
command allows the user to check their health metrics. These include their Height, Weight and Dieting Mode.
The metrics
command was implemented as MetricsCommand
in the diettracker/logic/commands
package.
The metrics
command has the following input format:
metrics
The following activity diagram illustrates what happens when a user executes the metrics
command:
Structure of Metrics Command
In this section, you will learn more about the relationships between objects related to the metrics
command.
The above class diagram shows the structure of the MetricsCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in MetricsCommand
Implementation of Metrics Command
The following is a detailed explanation of the operations MetricsCommand performs.
-
The
MetricsCommand#execute(DietModel dietModel)
method is executed. -
The
DietModel#printMetrics()
method would then be called to print the User’s Metrics. -
If successful, a success message will be generated by
CommandResult
and it will be returned with the generated success message. Otherwise, an error message showing the correct command syntax is thrown asCommandException
.
Sequence diagram for Metrics Command
The following sequence diagram summarizes what happens during the execution of metrics
command.
Dev Ops
Refer to the guide here.
Editing a Food in Diet Tracker
-
Editing a Food while all Foods are listed
-
Edit Command format:
edit -i INDEX [-n NAME] [-c CALORIES]
-
Prerequisites: List all Foods using the
list
command. Multiple Foods in the list. -
Test case:
edit -i 1 -n Pasta
Expected: First Food is edited. Details of the edited Food shown in the status message. Timestamp in the status bar is updated. Food is edited and then restored. -
Test case:
edit -i 1
Expected: No Food is edited. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
edit
,edit -i x
(where x is larger than the list size)
Expected: Similar to previous.
-
Calculate BMI In Diet Tracker
-
Calculating BMI for the User or for others.
-
Bmi Command format:
bmi [-h HEIGHT] [-w WEIGHT]
-
Test case:
bmi -h 170.2 -w 65.7
Expected: BMI will be calculated with the Height of 170.2cm and Weight of 65.7kg, and will be printed and shown to the user. The BMI category will also be displayed to the User. -
Test case:
bmi -h 170.2
Prerequisites: Must have stored Weight usingweight WEIGHT
. Expected: BMI will be calculated with the Height of 170.2cm and the User’s stored Weight, and will be printed and shown to the user. The BMI category will also be displayed to the User. -
Test case:
bmi -w 65.7
Prerequisites: Must have stored Weight usingheight HEIGHT
. Expected: BMI will be calculated with the User’s stored Height and the Weight of 65.7kg, and will be printed and shown to the user. The BMI category will also be displayed to the User. -
Test case:
bmi
Prerequisites: Must have stored Height usingheight HEIGHT
and Weight usingweight WEIGHT
. Expected: BMI will be calculated with the User’s stored Height and Weight, and will be printed and shown to the user. The BMI category will also be displayed to the User. -
Test case:
bmi -h 10000000000000000 -w 10000000000000000
Expected: Input height and weight are above the acceptable range. Error details shown in the response message. -
Other incorrect edit commands to try:
bmi -h -1
,bmi -h 137
(without storing Weight),bmi -w 67
(without storing Height)
Expected: BMI will not be calculated. Error Message will be shown with details.
-
Store Height In Diet Tracker
-
Storing Height into the Diet Tracker.
-
Height Command format:
height HEIGHT
-
Test case:
height 170.2
Expected: Stores a Height of 170.2cm into Diet Tracker. Details of the height stored are shown in success message. -
Test case:
height -1
Expected: Height will not be stored. Error details shown in the response message. -
Other incorrect height commands to try:
height 0
,height 1000000000000001
Expected: Height will not be stored. Expected: Error message shown with details.
-
Store Weight In Diet Tracker
-
Storing Weight into the Diet Tracker.
-
Height Command format:
weight WEIGHT
-
Test case:
weight 65.7
Expected: Stores a Weight of 65.7kg into Diet Tracker. Details of the weight stored are shown in success message. -
Test case:
weight -1
Expected: Weight will not be stored. Error details shown in the response message. -
Other incorrect weight commands to try:
weight 0
,weight 1000000000000001
Expected: Weight will not be stored. Error message shown with details.
-
Set Dieting Mode In Diet Tracker
-
Setting a Dieting Mode for Diet Tracker.
-
Mode Command format:
mode [-l] [-g] [-m]
-
Test case:
mode -l
Expected: Sets the Dieting Mode for the Diet Tracker and stores it. -
Test case:
mode
Expected: No Dieting Mode will be set. Error details shown in the response message.
-
Check User Metrics In Diet Tracker
-
Checking a Users own health metrics (Height, Weight and Dieting Mode).
-
Metrics Command format:
metrics
-
Test case:
metrics
Expected: The User’s own metrics will be printed out. -
Test case:
metrics -h
Expected: No metrics will be shown. Error details shown in the response message.
-
Questions to ask:
1. Should users be able to use BMI without input, or even with just a single (Height/Weight) input?
2. What is different for Calories than other Classes that are stored as attributes?