PROJECT: EYLAH


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:

    1. 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

    2. 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.

    3. 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.

    4. 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

    5. 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:

    1. 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.

    2. 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.

    3. 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.

    4. 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.

          DietTrackerActivityDiagram
          Figure 1. Diet Tracker Overall Activity Diagram
        • Drew Sequence Diagrams for various Diet Tracker functions.

DietTrackerAddCommandSequenceDiagram
Figure 2. Diet Tracker Add Command Sequence Diagram
DietTrackerDeleteCommandSequenceDiagram
Figure 3. Diet Tracker Delete Command Sequence Diagram
DietTrackerEditCommandSequenceDiagram
Figure 4. Diet Tracker Edit Command Sequence Diagram
DietTrackerListCommandSequenceDiagram
Figure 5. Diet Tracker List Command Sequence Diagram
  • Drew Class Diagrams for various Diet Tracker functions.

DietTrackerAddCommandClassDiagram
Figure 6. Diet Tracker Add Command Class Diagram
DietTrackerDeleteCommandClassDiagram
Figure 7. Diet Tracker Delete Command Class Diagram
DietTrackerEditCommandClassDiagram
Figure 8. Diet Tracker Edit Command Class Diagram
DietTrackerListCommandClassDiagram
Figure 9. Diet Tracker List Command Class Diagram
  • 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:

      • Updated Developer Guide to include Add and Delete Commands and their Sequence Diagrams (Pull request #177)

      • Update User Guide and Construct Summary Table (Pull request #255, Pull request #212, Pull request #377)

      • Updated all Use Cases for Developer Guide (Pull request #412)

    • Community:

      • PRs reviewed (with non-trivial review comments): (Pull request #209, Pull request #186, Pull request #372, Pull request #132)

      • Reported bugs and suggestions for other teams in the class: ped

    • 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:

dietTrackerAddCommandSuccessPhoto
Figure 10. Diet Tracker Add Command

Additional notes

  • Name and Calories are compulsory.

  • Tags are optional.

  • Any food that you add will be added based on the time that you keyed in the food data. As of Diet Tracker’s current functionalities, you cannot add in foods that you have consumed the day before while also setting that food to appear for the previous day’s data.


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

  • Deletes the food item at the specified INDEX of the list.

  • The index refers to the index number shown in the displayed food list.

  • The index must be a positive integer 1, 2, 3, …​

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:

dietTrackerDeleteCommandSuccessPhoto
Figure 11. Diet Tracker Delete Command

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:

dietTrackerListCommandSuccessPhoto
Figure 12. Diet Tracker List Command

Additional notes

  • Default value of list is food consumed for the day.

  • For the -d tag, the amount of days specified must be a positive Integer value.

  • Calorie intake based on mode is only shown when listing food for the day.


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]…​

  • -n NAME and -c CALORIES are compulsory fields.

  • There can be multiple -t TAG.

  • CALORIES can range from 0 to 1000000. Calories are implemented as Integers.

The following activity diagram illustrates what happens when a user executes the add command:

DietTrackerAddCommandActivityDiagram
Figure 13. Add Command Activity Diagram

Structure of Add Command

In this section, you will learn more about the relationships between objects related to the add command.

DietTrackerAddCommandClassDiagram
Figure 14. Add Command Class Diagram

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.

  1. 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.

  2. The Method DietModel#addFood(Food food) would be called to add the food into the FoodBook#foods.

  3. 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 as CommandException.

  4. If the command syntax was valid and Food was added to the FoodBook, LogicManager calls FoodBookStorage#saveFoodBook(ReadOnlyFoodBook foodBook) which saves the new Food Amount into JSON format after serializing it using JsonAdaptedFood.

Sequence diagram for Add Command

The following sequence diagram summarizes what happens during the execution of add command.

DietTrackerAddCommandSequenceDiagram
Figure 15. Add Command Sequence Diagram

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

  • INDEX is a compulsory field.

  • The Index of the Food must be retrieved by using the list command.

The following activity diagram illustrates what happens when a user executes the delete command:

DietTrackerDeleteCommandActivityDiagram
Figure 16. Delete Command Activity Diagram

Structure of Delete Command

In this section, you will learn more about the relationships between objects related to the delete command.

DietTrackerDeleteCommandClassDiagram
Figure 17. Delete Command Class Diagram

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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 as CommandException.

  5. If the command syntax was valid and Food was removed from FoodBook, LogicManager calls FoodBookStorage#saveFoodBook(ReadOnlyFoodBook foodBook) which saves the new Foods into JSON format after serializing it using JsonAdaptedFood.

Sequence Diagram for Delete Command

The following sequence diagram summarizes what happens during the execution of delete command.

DietTrackerDeleteCommandSequenceDiagram
Figure 18. Delete Command Sequence Diagram

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:

DietTrackerListCommandActivityDiagram
Figure 19. List Command Activity Diagram

Structure of List Command

In this section, you will learn more about the relationships between objects related to the list command.

DietTrackerListCommandClassDiagram
Figure 20. List Command Class Diagram

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.

  1. 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.

  2. 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.
  3. 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 as CommandException.

Sequence Diagram for List Command

DietTrackerListCommandAllSequenceDiagram
Figure 21. List Sequence Diagram for -a or No-Flag Input
DietTrackerListCommandDaySequenceDiagram
Figure 22. List Sequence Diagram for -d
DietTrackerListCommandTagSequenceDiagram
Figure 23. List Sequence Diagram for -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

  1. User chooses dieting mode (i.e. Weight Loss, Weight Gain, Maintain)

  2. EYLAH updates users' dieting mode

  3. User updates height

  4. EYLAH updates height of user

  5. User updates weight

  6. 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

  1. User adds food item

  2. 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

  1. User lists out existing items

  2. EYLAH shows the list based on flags entered

  3. User deletes item by index

  4. 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

  1. User lists out existing items

  2. EYLAH shows the list based on flags entered

  3. User edits item by index

  4. 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

  1. User lists out existing items

  2. 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

  1. User calls list command

  2. 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

  1. User calls bmi command, with optional height and weight entered

  2. 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

Add, Edit

-c

Calories

Add, Edit

-i

Index

Edit

-g

Gain

Mode

-m

Maintain

Mode

-l

Lose

Mode

-a

All

List

-d

By Past Num of Days

List

-t

By Tag

List

-h

Height

Bmi

-w

Weight

Bmi

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?