Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CS2113-W12-1] HealthMate #1

Open
wants to merge 537 commits into
base: master
Choose a base branch
from

Conversation

DarkDragoon2002
Copy link

Helping busy and CLI-affine people to build healthy eating habits to improve their mental and physical well-being.

Copy link

@wenxin-c wenxin-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good work from the team. Some minor suggestions for you to consider. Keep it up!!

* @param healthGoalInput the input health goal (e.g., WEIGHT_LOSS).
*/
public void saveHealthGoal(String healthGoalInput) {
assert healthGoalInput != null : "Health goal input cannot be null";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good use of assertion!!

Comment on lines 73 to 75
rawCaloriesTarget = 88.362 + (13.397 * weight) + (4.799 * height) - (5.677 * age);
} else {
rawCaloriesTarget = 447.593 + (9.247 * weight) + (3.098 * height) - (4.330 * age);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could consider turning the magic numbers into constant as well to give it a meaning.

Comment on lines 22 to 23
public static LocalDate currentDate() {
return LocalDate.now();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could try to name methods as verbs instead of noun, e.g. getCurrentData()

Comment on lines 120 to 122
} catch (NoSuchElementException e) {
// silent catch if existing user file contains no content
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try not to use empty catch block, you might want to implement some error catching/logging in the catch block.

Comment on lines 154 to 163
private void saveMealToFile(List<Meal> meals, String fileName) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(DATA_DIRECTORY + File.separator + fileName))) {
for (Meal meal : meals) {
writer.write(meal.toSaveString());
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is getting very long. One improvement you can consider is to extract such helper methods e.g. saving data to a file etc into a utils class and invoke relevant methods if needed.

private static final String FORMAT =
"add mealEntry {meal name from menu} | or | add mealEntry {meal name} /c{number of " + "calories}";
private static final String DESCRIPTION = "Adds a meal entry to the meal log either from a pre-existing meal in " +
"the" +

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could consider splitting the line at other places instead of having a single word on one line.

Comment on lines 82 to 84
public int size() {
return this.mealList.size();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to name this method as verb as well like other methods, e.g. getSize()


public Meal extractMealFromUserInput(String userInput) {
try {
String command = "save meal";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might consider extracting some string into named constant to give it some meaning.

Comment on lines 63 to 75
switch (userInput) {
case "bye":
logger.log(Level.INFO, "User closes application");
UI.printFarewell();
break;
default:
try {
this.multiCommandParsing(userInput, user);
logger.log(Level.INFO, "User input contains more than 1 token");
} catch (ArrayIndexOutOfBoundsException a) {
logger.log(Level.WARNING, "Invalid command", a);
UI.printReply("Invalid command", "Retry: ");
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there are no more potential cases to be added, you could consider just use a simple if...else.... switch will be more suitable if there are more cases.

Comment on lines 3 to 14
import seedu.healthmate.command.Command;
import seedu.healthmate.command.commands.LogMealsCommand;
import seedu.healthmate.command.commands.SaveMealCommand;
import seedu.healthmate.command.commands.ListCommandsCommand;
import seedu.healthmate.command.commands.AddMealEntryCommand;
import seedu.healthmate.command.commands.DeleteMealCommand;
import seedu.healthmate.command.commands.DeleteMealEntryCommand;
import seedu.healthmate.command.commands.MealMenuCommand;
import seedu.healthmate.command.commands.UpdateUserDataCommand;
import seedu.healthmate.command.commands.TodayCalorieProgressCommand;
import seedu.healthmate.command.commands.HistoricCalorieProgressCommand;
import seedu.healthmate.command.CommandMap;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good extraction of commands!!

Copy link

@cnivedit cnivedit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good attempt! Consider refining and adding more diagrams

To create or load a user profile the `User` class provides the method `checkForUserData` which loads
saved user information if available from an existing file usingn the `HistoryTracker` or prompts the user
to input new information for creating a new profile as shown in the sequence diagram below.
![User SD](images/userSequenceDiagram.jpg)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image Does the scanner instance exist prior to this point? If yes, there shouldnt be an activation bar for the constructor and in case it was newly created, perhaps there should be a call to the constructor?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
Perhaps consider omitting info about file creation as it may not be relevant to the purpose of the sequence diagram

For the sake of clarity, UI class is omitted since it is used across most classes to systematize any form of
printing output to the user.

![High Level CD](images/highLevelClassDiagram.jpg)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Should the class names be preceded with a colon?

The Meal class encapsulates the concept of a meal. As the purpose of this application
is to track calorie consumption, this consists of a mandatory calorie entry. The meal's name attribute,
is however an Optional<String> allowing a case, where no meaningful label can be attached to a certain consumption.
![User SD](images/addMeal.png)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
Image fails to load

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the sequence diagram omit program execution prior to when add meal command is detected?

Copy link

@kaboomzxc kaboomzxc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall DG is okay good 👍🏻

Comment on lines 26 to 27
For the sake of clarity, UI class is omitted since it is used across most classes to systematize any form of
printing output to the user.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

although I understand that you mentioned Ui class is omitted for clarity, however my modest opinion is that Ui is crucial component to be documented. would a separate UI class diagram be useful?

Comment on lines 277 to 278
8. Error Handling:
- Try entering invalid commands or data to ensure the application handles errors gracefully and provides helpful error messages.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be favourable to show some examples?

Comment on lines 66 to 69
public double getTargetCalories(double height, double weight, boolean isMale, int age) {
assert height > 0 : "Height must be positive";
assert weight > 0 : "Weight must be positive";
assert age > 0 : "Age must be positive";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good to guard against negative height/weight/age !
I am wondering, would it be useful to guard against unrealistic data such as 500 yrs of Age ?

For the sake of clarity, UI class is omitted since it is used across most classes to systematize any form of
printing output to the user.

![High Level CD](images/highLevelClassDiagram.jpg)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good separation of concerns between classes !

Comment on lines +30 to +31

#### HealthMate

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear explanation of classes


HistoryTracker allows for the persistance of user inputted data between sessions by storing it in a local csv file.

## Features

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could some Sequence Diagrams of the processing of Commands be shown?

![User SD](images/userSequenceDiagram.jpg)
Reference diagrams used
![User SD](images/askForUserDataSD.png)
![Read User SD](images/readUserDataFromFileSD.png)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good decision to show two sub-diagrams for clarity; creating a new profile for new user, and loading saved file for existing user

---
### Creating a User Profile
To create or load a user profile the `User` class provides the method `checkForUserData` which loads
saved user information if available from an existing file usingn the `HistoryTracker` or prompts the user

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found a minor typo hehe , "using" is the correct spelling instead of "usingn"

This specifically includes adherance to the "Tell Don't Ask" principle which was enforced by
making most attributes of all classes above private and avoiding getter methods if possible.
The following diagram illustrates the resulting associations, methods and attributes.
For the sake of clarity, UI class is omitted since it is used across most classes to systematize any form of

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be helpful to include a minimal/simple representation of the UI class in the high level class diagram to indicate dependency across all classes. this might improve clarity around UI interactions

To create or load a user profile the `User` class provides the method `checkForUserData` which loads
saved user information if available from an existing file usingn the `HistoryTracker` or prompts the user
to input new information for creating a new profile as shown in the sequence diagram below.
![User SD](images/userSequenceDiagram.jpg)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree with cnivedit about the Scanner instance's activation bar. additionally, if scanner is indeed reused across multiple interactions, would it make sense to show its initialisation outside the main sequence flow?

The Meal class encapsulates the concept of a meal. As the purpose of this application
is to track calorie consumption, this consists of a mandatory calorie entry. The meal's name attribute,
is however an Optional<String> allowing a case, where no meaningful label can be attached to a certain consumption.
![User SD](images/addMeal.png)
Copy link

@kennethszj kennethszj Oct 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
the sequence for extractAndAppendMeal() is clear in showing that a meal object is created and appended.
Would it be clearer to describe what information is extracted? like what does this method extract (eg, name, calorie...)

to input new information for creating a new profile as shown in the sequence diagram below.
![User SD](images/userSequenceDiagram.jpg)
Reference diagrams used
![User SD](images/askForUserDataSD.png)
Copy link

@kennethszj kennethszj Oct 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

in the sequence, "printString(...)" is used multiple times. would it be more readable to differentiate each print string with specific text or parameters? (eg, printstring(enter calorie:)). this could help viewers understand what actual prompt is displayed at each step.

Copy link

@jadenlimjc jadenlimjc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall a good DG, perhaps the Command Handling Section could do with some sequence diagrams or examples of inputs to aid clarity

This specifically includes adherance to the "Tell Don't Ask" principle which was enforced by
making most attributes of all classes above private and avoiding getter methods if possible.
The following diagram illustrates the resulting associations, methods and attributes.
For the sake of clarity, UI class is omitted since it is used across most classes to systematize any form of

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likewise to previous reviewers, my belief is that some documentation of the UI component would be useful in order to provide clarity into possible outputs a user should receive. perhaps you could separate the UI diagram form the overarching diagram provided to retain the clarity your diagram currently has while still providing viewers with the information regarding the UI class.

- A `MealList` object called `mealOptions`
- Contains meals that are presaved by the user for quick selection to track commonly consumed meals
- the command `meal menu` is used to display the current mealOptions. The implementation of this command is shown in the UML diagram below.
![Meal Menu SD](images/mealMenuSD.png)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps the diagram could include a user so that the run() function does not appear out of nowhere, providing additional clarity.

To create or load a user profile the `User` class provides the method `checkForUserData` which loads
saved user information if available from an existing file usingn the `HistoryTracker` or prompts the user
to input new information for creating a new profile as shown in the sequence diagram below.
![User SD](images/userSequenceDiagram.jpg)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personally, this image used is quite blurry and the details are hard to see regardless of zoom. perhaps the team could consider making the diagram slightly easier on the eyes to improve user experience. another possible solution could be to break the diagram into smaller independent sections. as cnivedit mentioned, the file creation may not be the mos relevant to the creation of a user profile so can consider depicting file creation in a separate diagram.

Dri-water and others added 30 commits November 11, 2024 21:29
…ssing-t-in-list-commands-documentation

Fix: add documentation to add meal entry
Fix: Renamed PPP according to submission guidelines
…ssing-t-in-list-commands-documentation

Fix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants