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 enhancement: [In Process]
-
What it does:
-
Justification:
-
Highlights:
-
Credits: {mention here if you reused any code/ideas from elsewhere or if a third-party library is heavily used in the feature so that a reader can make a more accurate judgement of how much effort went into the feature}
-
-
Major Enhancements:
-
Refactored entire AB3 Code base to be used for EYLAH (Refactoring Codebase - Pull request #126
-
What it does:
The idea was to allow both the Expense Splitter and Diet Tracker features of EYLAH to be built onto the existing AB3 framework rather than replace it entirely. -
Justification:
The partitioning into the two feature sections during the refactoring meant that it would be easy to extend the app in the future when adding more new features. It would also allow the two teams for each of the features work independently without much conflict of code, especially during the initial building phase where there are bound to be many bugs. Building on the existing AB3 code base also meant that we were able to follow the good practices and structure used. -
Highlights:
As we had already started development of the two features before the refactoring, the highlight was trying to understand the existing structure at that point to refactor and partition without introducing any bugs. This required working together with my teammates to understand the functionality they had started to implement. -
Credits:
Address Book 3 Code Base
-
-
Adding of Food, Calories and Date classes, their test classes for the Diet Tracker (Food, Calories, Tests - Pull request #104 & Pull request #125 & Pull request #111) (Date - Pull request #104)
-
What it does:
Food is used to represent a food item to be added into the diet tracker and it stores a Calorie object that contains the number of calories in the food. -
Justification:
These classes are what the Diet Tracker is built upon as almost every command uses the classes to track the food intake of users. Without these classes, users would be unable to track the food they eat and their calorie intake. Date was added subsequently to allow for functionality of tracking food by date. -
Highlights:
The highlight was understanding the requirements of a user when using the Diet Tracker and translating them into the Food class. For example, for a diet tracker a user would want a food item that they store to have calories so as to track and a name to remember by. It was also interesting to understand how date was to be stored. Instead of serializing the LocalDateTime object, I decided to store as a string and call the parser that Java offers to convert it back. -
Credits:
AB3 Code Base on how Person is being modelled and used. Duke for the idea of using LocalDateTime.
-
-
Implement Storage for Diet Tracker in EYLAH
-
What it does:
Store food data of user so that when the app is restarted, the information still exists. (Storage - Pull request #152 & #210) -
Justification:
Users will not constantly keep the app open and there are times when they would close it,thus, storage allows users to close the app and continue where they left off without doing all the work again. -
Highlights: It was quite a challenge dealing with the storage due to the complex nature of translating Java objects into a form that can be stored in a Json. There were several issues, such as data being able to be stored but no read when the app was re-initialised.
-
Credits: Would like to credit all my team mates in discussing and deciding that in this case the best way to store would be as a JSON rather than a string and also helping me with troubleshooting storage issues.
-
-
Implement Add, Delete Commands and relevant tests
-
What it does:
Allows for food to be added and removed. (Add, Delete - Pull request #128) (Tests - Pull request #242) -
Justification:
The core functionality of a diet tracking app is to be able to control the food in the app, that the Add and Delete commands let you do. -
Highlights: It was intriguing to understand the LogicManager as this was my first implementation of logic components.
-
Credits: Address Book 3
-
-
Implement various list command (Daily, By Tag, By Time Period, All)
-
What it does:
This allows the list shown to change based on the flag provided by the user. They can view daily list, filter by tag, filter by time period or view all consumption ever. (List Fix - Pull request #210) (List By Tag - Pull request #221) (List By Past Num of Days - Pull request #225) (Refactor Flags For Each Type - #248) -
Justification:
Instead of simply listing out all the food, there are different list commands for different user needs. If the user wants to track his daily consumption, they can view the daily list, if they wish to find a certain type of food, they can filter by tag and if they want to know what they ate over a past number of days they can use time period. -
Highlights: The incorporation of the various list command types was not straightforward as it did not just require changes in the List Command but also required addition of date and tags into food to be filtered.
-
Credits: My team mate, Jarrod for the idea on having different types of lists to serve different user functions
-
-
-
Minor enhancement:
-
Show Total Calories Intake and Calories left based on Mode
(Total Calorie Count - Pull request #248) (Show Remaining Calories - Pull request #356)-
What it does:
Tabulate the total calorie intake for the day and display to the user. Based on the mode, obtain the calorie limit and let the user know how many more calories he can take or whether he has hit the limit. -
Justification:
Knowing how many calories have been taken in and how much more one can eat would let the user better track his diet to know whether to consume more or less.
-
-
Fix Several Failing Tests
(Fix Bmi, Mode, Height, Weight Tests - Pull request #375) (Fix AddCommand, ListCommand, LogicManager Tests - Pull request #247) (Fix JsonFoodBookStorage Test - Pull request #243) (Fix Add, Delete, List Test - Pull request #242)-
What it does:
There were many test methods that were failing. -
Justification:
The classes would not be able to be rigorously tested if the assertions do not work. This also meant that we potentially had problems in our code if the test classes were correct. -
Highlights
It was extremely hard to understand why the tests were failing, thus, required extensive logging and tracing to find out problems in the code.
-
-
Fix Storage Bugs
(Storing of height, weight, mode - Pull request #318) (Reading height, weight from storage - Pull request #362) (Reading existing JSON - Pull request #210)-
What it does:
There were many bugs with storage, first when implementing storage for food and subsequently when implementing storage for personal metrics. For the storing for food, it was being saved to a JSON but could not be loaded when app was re-initialised. For the storing of personal metrics, there was issue with generating of the JSON file. -
Highlights
Similar to the bugs with tests, it was quite challenging to figure out my values were not able to be stored or read.
-
-
Fix Overflow Bug For Number Of Days
(Num of Days Overflow - Pull request #373)-
What it does:
There was an issue during internal testing where extremely large values would cause overflow even when the data type was a long. -
Highlights
There was much discussion on where to handle this and impose a limit. Here, I imposed a limit in the parser based on the size of the input string and taking into consideration the average lifespan of a human.-
Drew Activity Diagrams for various Diet Tracker functions.
Figure 1. Diet Tracker Overall Activity Diagram -
Drew Sequence Diagrams for various Diet Tracker functions.
-
-
-
-
Drew Class Diagrams for various Diet Tracker functions.
-
Code contributed: Functional Code and Test Code
-
Other contributions:
-
Project management:
-
In charge of refactoring initial codebase to be used for Expense Splitter and Diet Tracker.
-
In charge of Diet Tracker functionalities for EYLAH.
-
Incorporated
-
Participated in planning the project timeline for EYLAH.
-
-
Enhancements to existing features:
-
Adapted existing storage functionality of Address Book for Diet Tracker. (Pull request #152)
-
-
Documentation:
-
Community:
-
Tools:
-
Code contributed
Please click the following link to see my code contributions dashboard. Code Report
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. |
Adding food add
In this section, you will learn more about the add
command, how to use it
and the expected outcome after using the
add
command.
Summary of Add Command:
add
You can use this command to add a food to the list.
How to use the Add Command:
Format:
add -n NAME -c CALORIES [-t TAG]…
Valid Example:
add -n Fishball Noodles -c 383 -t favourite -t noodles
Expected outcome:
Additional notes
|
Deleting a Food Item delete
In this section, you will learn more about the delete
command, how to use it
and the expected outcome after using the
delete
command.
Summary of Delete Command:
delete
You can delete a food item based on the previous list of Foods that you have listed.
How to use the Delete Command:
Format:
delete INDEX
Valid Example:
list
delete 2
Deletes the 2nd row of food data from today’s list of food.
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 delete. |
Listing items list
In this section, you will learn more about the list
command, how to use it
and the expected outcome after using the
list
command.
Summary of List Command:
list
You can use this function to list out the different foods that you have consumed and their total calories.
Different listing modes allow you to watch your overall diet during the period, or how much you can/should eat based
on your daily intake.
Displays different data based on the below flags:
-
Food consumed for the day (NO FLAG)
-
All food ever consumed (-a)
-
Food consumed for the past number of days (-d)
-
All food with the given tag (-t)
How to use the List Command:
Format:
list [-a] [-d NUMDAYS] [-t TAGNAME]
Valid Examples:
list
list -a
list -d 3
list -t healthy
Expected outcome:
Additional notes
|
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. |
Add Command
In this section, we will learn more about how the add
command is implemented.
What is the Add Command
The add
command allows the user to add a Food into the FoodBook, along with the Name of the Food and the Calories of the Food.
The add
command was implemented as AddCommand
in the diettracker/logic/commands
package.
The add
command has the following input format:
add
-n NAME
-c CALORIES
[-t TAG]…
|
The following activity diagram illustrates what happens when a user executes the add
command:
Structure of Add Command
In this section, you will learn more about the relationships between objects related to the add
command.
The above class diagram shows the structure of the AddCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in AddCommand
Implementation of Add Command
The following is a detailed explanation of the operations AddCommand performs.
-
The
AddCommand#execute(Model dietModel)
method is executed and it checks if the specified Name and Calories of a given Food to be added are valid. If valid, a new Food would be created with the specified Name and Calories. -
The Method
DietModel#addFood(Food food)
would be called to add the food into theFoodBook#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 added to the FoodBook,
LogicManager
callsFoodBookStorage#saveFoodBook(ReadOnlyFoodBook foodBook)
which saves the new Food Amount into JSON format after serializing it usingJsonAdaptedFood
.
Sequence diagram for Add Command
The following sequence diagram summarizes what happens during the execution of add
command.
Delete Command
In this section, we will learn more about how the delete
command is implemented.
What is the Delete Command
The delete
command allows users to remove the Food from the FoodBook via the Index.
The delete
command was implemented as DeleteCommand
in the diettracker/logic/commands
package.
The delete
command has the following input format:
delete
INDEX
|
The following activity diagram illustrates what happens when a user executes the delete
command:
Structure of Delete Command
In this section, you will learn more about the relationships between objects related to the delete
command.
The above class diagram shows the structure of the DeleteCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in DeleteCommand
Implementation
The following is a detailed explanation of the operations DeleteCommand performs.
-
The
DeleteCommand#execute(Model dietModel)
method is executed and it validates that the specified Index to delete is within range. If valid, the Food to be deleted will be retrieved from FoodBook using its Index. -
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 deleted. -
The method
DietModel#deleteFood(Food food)
will then be called to remove the Food from the FoodBook.FoodBook#remove(int Index)
is invoked which makes a call to its internal list to remove the specified Food. -
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 removed from FoodBook,
LogicManager
callsFoodBookStorage#saveFoodBook(ReadOnlyFoodBook foodBook)
which saves the new Foods into JSON format after serializing it usingJsonAdaptedFood
.
Sequence Diagram for Delete Command
The following sequence diagram summarizes what happens during the execution of delete
command.
List Command
In this section, we will learn more about how the list
command is implemented.
What is the List Command
The list
command allows users to find out the current Foods in the FoodBook over a period of time as specified by the flag,
or a list of foods with the specified tag.
The list
command was implemented as a ListCommand
in the diettracker/logic/commands
package.
The list
has the following input format:
list
[-a]
[-d DAYS]
[-t TAGS]
Users must only enter at most ONE flag when using the list command. |
The following activity diagram illustrates what happens when a user executes list
command:
Structure of List Command
In this section, you will learn more about the relationships between objects related to the list
command.
The above class diagram shows the structure of the ListCommand
and its associated classes and
interfaces. Some methods and fields are left out because they are not of concern in ListCommand
Implementation of List Command
The following is a detailed explanation of the operations ListCommand
performs.
-
The
ListCommand#execute(DietModel dietModel)
method is executed and it validates that the flag used to decide what Foods to list. If the flag is valid, the items to be listed will be retrieved from DietModel according to the input flag. -
The method
DietModel#updateFilteredFoodList() will then be called to filter the List of Foods in DietModel. `FilteredList#setPredicate(Predicate<Food> predicate)
is then invoked which retrieves the specified Foods to be listed.Case No-Flag Input: The Predicate is any food with date within 1 day back from current time.
Case `-a`: The Predicate always returns true so the list is the entire FoodBook.
Case `-d`: The Predicate will be all food with date later than the specified date which is calculated by input number of days back from the current date.
Case `-t`: The Predicate will be any food with tags that matches given time.
-
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 List Command
-a
or No-Flag Input-d
-t
Appendix A: Use Cases
(For all use cases below, the System is the EYLAH
and the Actor is the user
, unless specified otherwise)
Diet Tracker Use Cases
Use case: UC01 Update User Profile
Actor: User
User’s Height, Weight and Mode will be updated in Self.
MSS
-
User chooses dieting mode (i.e. Weight Loss, Weight Gain, Maintain)
-
EYLAH updates users' dieting mode
-
User updates height
-
EYLAH updates height of user
-
User updates weight
-
EYLAH updates weight of user
Use case ends.
Extensions
-
1a. The flag field for dieting mode is empty or flag is invalid.
-
1a1. EYLAH requests user to re-enter command with flag
-
1a2. User enters command with flag
Steps 1a1-1a2 are repeated until the correct entered is correct.
Use case resumes from step 2.
-
-
3a. Height field is empty or in invalid format.
-
3a1. EYLAH requests user to re-enter height in correct format
-
3a2. User enters command with height in correct format
Steps 3a1-3a2 are repeated until the correct entered is correct.
Use case resumes from step 4.
-
-
3b. Height value is too large and beyond the limit.
-
3b1. EYLAH tells user the limit for the height value and prompts to re-enter command.
-
3b2. User will input values within the specified range.
Steps 3b1-3b2 are repeated until the command entered is correct.
Use case resumes from step 4.
-
-
5a. Weight field is empty or in invalid format.
-
5a1. EYLAH requests user to re-enter weight in correct format
-
5a2. User enters command with weight in correct format
Steps 5a1-5a2 are repeated until the correct entered is correct.
Use case resumes from step 6.
-
-
5b. Weight value is too large and beyond the limit.
-
5b1. EYLAH tells user the limit for the weight value and prompts to re-enter command.
-
5b2. User will input values within the specified range.
Steps 5b1-5b2 are repeated until the command entered is correct.
Use case resumes from step 6.
-
-
*a. At any time, User chooses to not proceed after inputting in invalid command.
-
*a1. EYLAH will not make any changes
Use case ends.
-
Use case: UC02 Add Food Item
Actor: User
Food will be added into FoodBook.
MSS
-
User adds food item
-
EYLAH adds food item to user’s log
Use case ends.
Extensions
-
1a. The food item is added in an invalid format or certain fields are missing.
-
1a1. EYLAH requests user to re-enter food item in valid format.
-
1a2. User enters command in the correct format as requested by EYLAH
Steps 1a1-1a2 are repeated until the correct entered is correct.
Use case resumes from step 2.
-
-
*a. At any time, User chooses to not proceed after inputting in invalid command.
-
*a1. EYLAH will not make any changes
Use case ends.
-
Use case: UC03 Delete Food Item
Actor: User
Food will be deleted from FoodBook.
MSS
-
User lists out existing items
-
EYLAH shows the list based on flags entered
-
User deletes item by index
-
EYLAH deletes item tagged to specified index
Use case ends.
Extensions
-
1a. List command contains invalid flag.
-
1a1. EYLAH will show proper usage of the command and the valid flags.
-
1a2. User will re-enter the command with a valid flag.
Steps 1a1-1a2 are repeated until the command entered is correct. Use case resumes from step 2.
-
-
3a. Invalid or empty index keyed into command.
-
3a1. EYLAH requests user to re-enter index in correct format
-
3a2. User enters edit in correct format
Steps 3a1-3a2 are repeated until the command entered is correct.
Use case ends. Use case resumes from step 4.
-
-
*a. At any time, User chooses to not proceed after inputting in invalid command.
-
*a1. EYLAH will not make any changes
Use case ends.
-
Use case: UC04 Edit Food Item
Actor: User
Food in FoodBook will be edited.
MSS
-
User lists out existing items
-
EYLAH shows the list based on flags entered
-
User edits item by index
-
EYLAH edits the data of the item stored at the index.
Use case ends.
Extensions
-
1a. List command contains invalid flag.
-
1a1. EYLAH will show proper usage of the command and the valid flags.
-
1a2. User will re-enter the command with a valid flag.
Steps 1a1-1a2 are repeated until the command entered is correct. Use case resumes from step 2.
-
-
3a. Invalid or empty index keyed into command.
-
3a1. EYLAH requests user to re-enter index in correct format
-
3a2. User enters edit in correct format
Steps 3a1-3a2 are repeated until the command entered is correct.
Use case resumes from step 4.
-
-
3b. No additional tags and data keyed in as flags to replace existing data.
-
3b1. EYLAH requests user to re-enter command with at least one flag
-
3b2. User enters command with flag and data
Steps 3b1-3b2 are repeated until the command entered is correct.
Use case resumes from step 4.
-
-
*a. At any time, User chooses to not proceed after inputting in invalid command.
-
*a1. EYLAH will not make any changes
Use case ends.
-
Use case: UC05 List Food Items
Actor: User
List food in FoodBook filtered by tags.
MSS
-
User lists out existing items
-
EYLAH shows the list based on flags entered
Use case ends.
Extensions
-
1a. Invalid flag or additional arguments are entered into the command.
-
1a1. EYLAH will show proper usage of the command and the valid flags.
-
1a2. User will re-enter the command with a valid flag.
Steps 1a1-1a2 are repeated until the command entered is correct. Use case resumes from step 2.
-
-
*a. At any time, User chooses to not proceed after inputting in invalid command.
-
*a1. EYLAH will not make any changes
Use case ends.
-
Use case: UC06 Track Daily Calories
Actor: User
Show user daily food and calorie intake.
MSS
-
User calls
list
command -
EYLAH shows food intake for the day, calories intake for the day, and calories left to consume
Use case ends.
Extensions
-
1a. Additional valid flags entered with the list command.
-
1a1. EYLAH would generate and display the appropriate list according to the flag
User case ends.
-
-
*a. At any time, User chooses to not proceed after inputting in invalid command.
-
*a1. EYLAH will not make any changes
Use case ends.
-
Use case: UC07 Calculate BMI
Actor: User
Calculate BMI for user.
MSS
-
User calls
bmi
command, with optional height and weight entered -
EYLAH calculates and shows user’s BMI based on the height and weight
Use case ends.
Extensions
-
1a. BMI command contains invalid flags.
-
1a1. EYLAH suggests to user the correct format to use
-
1a2. User will key in the correct format
Steps 1a1-1a2 are repeated until the command entered is correct.
Use case resumes from step 2.
-
-
1b. Both height and weight are not provided as input and there is no stored height and weight.
-
1b1. EYLAH tells user to provide both height and weight as there are no stored values
-
1b2. User will input both height and weight values.
Steps 1b1-1b2 are repeated until the command entered is correct.
Use case resumes from step 2.
-
-
1c. Height is not provided as input and there is no stored height.
-
1c1. EYLAH tells user to provide height as there are no stored value.
-
1c2. User will input height value with the bmi command.
Steps 1c1-1c2 are repeated until the command entered is correct.
Use case resumes from step 2.
-
-
1d. Weight is not provided as input and there is no stored weight.
-
1d1. EYLAH tells user to provide weight as there are no stored value.
-
1d2. User will input Weight value with the bmi command.
Steps 1d1-1d2 are repeated until the command entered is correct.
Use case resumes from step 2.
-
-
1e. Height and weight values are extremely large and beyond the limit.
-
1e1. EYLAH tells user the limit for the values and prompts to re-enter command.
-
1e2. User will input values within the specified range.
Steps 1e1-1e2 are repeated until the command entered is correct.
Use case resumes from step 2.
-
-
*a. At any time, User chooses to not proceed after inputting in invalid command.
-
*a1. EYLAH will not make any changes
Use case ends.
-
Table 1. Diet Tracker Command Prefix
Prefix |
Description |
Used in Following Commands |
-n |
Name of Food |
|
-c |
Calories |
|
-i |
Index |
|
-g |
Gain |
|
-m |
Maintain |
|
-l |
Lose |
|
-a |
All |
|
-d |
By Past Num of Days |
|
-t |
By Tag |
|
-h |
Height |
|
-w |
Weight |
Questions to ask:
1. Is JSON the most optimal way of storing the data? Would text files have been more appropriate in this instance?
2. Are there additional attributes that should be in a food?