Skip to content

Commit

Permalink
Add gender (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
marklin2234 authored Nov 4, 2023
1 parent b6f321e commit 42da67b
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 69 deletions.
20 changes: 12 additions & 8 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,20 @@ Goodbye! Hope to see you again soon!
### Editing Your Profile: `editprofile`
Allows user to edit their profile details.

Format: `editprofile h/<height> w/<weight> l/<calories>`
Format: `editprofile h/<height> w/<weight> g/<gender> l/<calories>`

Example of usage:
```
editprofile h/170 w/70 l/100
editprofile h/170 w/70 g/M l/100
```
Expected output:
```
I've edited the following:
Height: 170.0
Weight: 70.0
Daily calorie limit: 100.0
Height: 170.0cm
Weight: 70.0kg
Daily calorie limit: 100.00
BMI: 100.00
Gender: Male
```

### Viewing your profile: `viewprofile`
Expand All @@ -100,9 +102,11 @@ viewprofile
**Expected output:**
```
Your Profile:
Height: 180.0
Weight: 80.0
Daily calorie limit: 3000.0
Height: 100.0cm
Weight: 100.0kg
Daily calorie limit: 1000kcal
BMI: 100.00
Gender: Male
```

### Checking your current BMI: `bmi`
Expand Down
10 changes: 7 additions & 3 deletions src/main/java/fittrack/FitTrack.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import fittrack.parser.NegativeNumberException;
import fittrack.parser.NumberFormatException;
import fittrack.parser.PatternMatchFailException;
import fittrack.parser.WrongGenderException;
import fittrack.storage.Storage;
import fittrack.storage.Storage.StorageOperationException;
import fittrack.storage.Storage.InvalidStorageFilePathException;
Expand Down Expand Up @@ -73,11 +74,13 @@ private void start(String[] args) {
profileSettings();
isValidInput = true;
} catch (PatternMatchFailException e) {
System.out.println("Wrong format. Please enter h/<height> w/<weight> l/<dailyCalorieLimit>");
System.out.println("Wrong format. Please enter h/<height> w/<weight> g/<gender> l/<dailyCalorieLimit>");
} catch (NumberFormatException e) {
System.out.println("Please enter numbers for height, weight, and daily calorie limit.");
} catch (NegativeNumberException e) {
System.out.println("Please enter a number greater than 0");
} catch (WrongGenderException e) {
System.out.println("Please enter either M or F");
}
}
}
Expand Down Expand Up @@ -110,9 +113,9 @@ private CommandResult executeCommand(Command command) {
* @throws NumberFormatException if one of arguments is not double
*/
private void profileSettings()
throws PatternMatchFailException, NumberFormatException, NegativeNumberException {
throws PatternMatchFailException, NumberFormatException, NegativeNumberException, WrongGenderException {
System.out.println(
"Please enter your height (in cm), weight (in kg), and daily calorie limit (in kcal):"
"Please enter your height (in cm), weight (in kg), gender (M or F), and daily calorie limit (in kcal):"
);
String input = ui.scanNextLine();

Expand All @@ -122,6 +125,7 @@ private void profileSettings()
userProfile.setHeight(profile.getHeight());
userProfile.setWeight(profile.getWeight());
userProfile.setDailyCalorieLimit(profile.getDailyCalorieLimit());
userProfile.setGender(profile.getGender());

ui.printProfileDetails(userProfile);
}
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/fittrack/UserProfile.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package fittrack;

import fittrack.data.Height;
import fittrack.data.Gender;
import fittrack.data.Weight;
import fittrack.data.Height;
import fittrack.data.Calories;
import fittrack.data.Bmi;

Expand All @@ -10,15 +11,17 @@ public class UserProfile {
private Weight weight;
private Calories dailyCalorieLimit;
private Bmi bmi;
private Gender gender;

public UserProfile() {
this(new Height(1), new Weight(1), new Calories(0));
this(new Height(1), new Weight(1), new Calories(0), new Gender('M'));
}

public UserProfile(Height height, Weight weight, Calories dailyCalorieLimit) {
public UserProfile(Height height, Weight weight, Calories dailyCalorieLimit, Gender gender) {
this.height = height;
this.weight = weight;
this.dailyCalorieLimit = dailyCalorieLimit;
this.gender = gender;
updateBmi();
}

Expand All @@ -40,6 +43,14 @@ public void setWeight(Weight weight) {
updateBmi();
}

public Gender getGender() {
return gender;
}

public void setGender(Gender gender) {
this.gender = gender;
}

public Calories getDailyCalorieLimit() {
return dailyCalorieLimit;
}
Expand All @@ -64,6 +75,7 @@ public String toString() {
return "Height: " + height.toString() + "\n" +
"Weight: " + weight.toString() + "\n" +
"Daily calorie limit: " + dailyCalorieLimit.toString() + "\n" +
"BMI: " + bmi.toString();
"BMI: " + bmi.toString() + "\n" +
"Gender: " + gender.toString();
}
}
2 changes: 1 addition & 1 deletion src/main/java/fittrack/command/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void setData(UserProfile userProfile, MealList mealList, WorkoutList work
* @param parser parser
* @throws ParseException if parse fails
*/
public abstract void setArguments(String args, CommandParser parser)
public abstract void setArguments(String args, CommandParser parser)
throws ParseException;

/**
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/fittrack/command/EditProfileCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import fittrack.parser.NegativeNumberException;
import fittrack.parser.NumberFormatException;
import fittrack.parser.PatternMatchFailException;
import fittrack.parser.WrongGenderException;

public class EditProfileCommand extends Command {
public static final String COMMAND_WORD = "editprofile";
private static final String DESCRIPTION =
String.format("`%s` allows you to edit your profile.", COMMAND_WORD);
private static final String USAGE =
String.format("Type `%s h/<HEIGHT> w/<WEIGHT> l/<CALORIE_LIMIT>` to edit.", COMMAND_WORD);
String.format("Type `%s h/<HEIGHT> w/<WEIGHT> g/<GENDER> l/<CALORIE_LIMIT>` to edit.", COMMAND_WORD);
public static final String HELP = DESCRIPTION + "\n" + USAGE;

UserProfile newProfile;
Expand All @@ -25,12 +26,13 @@ public CommandResult execute() {
userProfile.setHeight(newProfile.getHeight());
userProfile.setWeight(newProfile.getWeight());
userProfile.setDailyCalorieLimit(newProfile.getDailyCalorieLimit());
userProfile.setGender(newProfile.getGender());
return new CommandResult("Here is your updated profile:\n" + userProfile.toString());
}

@Override
public void setArguments(String args, CommandParser parser)
throws PatternMatchFailException, NumberFormatException, NegativeNumberException {
throws PatternMatchFailException, NumberFormatException, NegativeNumberException, WrongGenderException {
newProfile = parser.parseProfile(args);
}

Expand Down
22 changes: 22 additions & 0 deletions src/main/java/fittrack/data/Gender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package fittrack.data;

public class Gender {
private char gender;

public Gender(char gender) {
this.gender = gender;
}

public char getGender() {
return gender;
}

public void setGender(char gender) {
this.gender = gender;
}

@Override
public String toString() {
return gender == 'M' ? "Male" : "Female";
}
}
30 changes: 21 additions & 9 deletions src/main/java/fittrack/parser/CommandParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
import fittrack.command.ViewWorkoutsCommand;
import fittrack.command.FindMealCommand;
import fittrack.command.FindWorkoutCommand;
import fittrack.data.Gender;
import fittrack.data.Meal;
import fittrack.data.Workout;
import fittrack.data.Weight;
import fittrack.data.Height;
import fittrack.data.Calories;
import fittrack.data.Workout;
import fittrack.data.Date;
import fittrack.data.Height;
import fittrack.data.Weight;


import java.time.format.DateTimeParseException;
import java.util.regex.Matcher;
Expand All @@ -51,6 +53,7 @@ public class CommandParser {
private static final String ARGS_CG = "args";
private static final String HEIGHT_CG = "height";
private static final String WEIGHT_CG = "weight";
private static final String GENDER_CG = "gender";
private static final String CAL_LIMIT_CG = "calLimit";
private static final String NAME_CG = "name";
private static final String CALORIES_CG = "calories";
Expand All @@ -61,7 +64,8 @@ public class CommandParser {
"(?<" + WORD_CG + ">\\S+)(?<" + ARGS_CG + ">.*)"
);
private static final Pattern PROFILE_PATTERN = Pattern.compile(
"h/(?<" + HEIGHT_CG + ">\\S+)\\s+w/(?<" + WEIGHT_CG + ">\\S+)\\s+l/(?<" + CAL_LIMIT_CG + ">\\S+)"
"h/(?<" + HEIGHT_CG + ">\\S+)\\s+w/(?<" + WEIGHT_CG +
">\\S+)\\s+g/(?<" + GENDER_CG + ">\\S+)\\s+l/(?<" + CAL_LIMIT_CG + ">\\S+)"
);
private static final Pattern MEAL_PATTERN = Pattern.compile(
"(?<" + NAME_CG + ">.+)\\s+c/(?<" + CALORIES_CG + ">\\S+)(\\s+d/(?<" + DATE_CG + ">\\S+))?"
Expand Down Expand Up @@ -167,29 +171,37 @@ public CommandResult getInvalidCommandResult(String userCommandLine, ParseExcept
* @throws NumberFormatException if one of arguments is not double
*/
public UserProfile parseProfile(String profile)
throws PatternMatchFailException, NumberFormatException, NegativeNumberException {
throws PatternMatchFailException, NumberFormatException, NegativeNumberException, WrongGenderException {
final Matcher matcher = PROFILE_PATTERN.matcher(profile);
if (!matcher.matches()) {
throw new PatternMatchFailException();
}

try {
final double height = Double.parseDouble(matcher.group(HEIGHT_CG));
final double weight = Double.parseDouble(matcher.group(WEIGHT_CG));
final double dailyCalorieLimit = Double.parseDouble(matcher.group(CAL_LIMIT_CG));
final double height = Double.parseDouble(matcher.group("height"));
final double weight = Double.parseDouble(matcher.group("weight"));
final double dailyCalorieLimit = Double.parseDouble(matcher.group("calLimit"));
final char gender = matcher.group("gender").charAt(0);

// Height, weight and calories cannot be negative. Throw exception if it happens
if (height < 0 || weight < 0 || dailyCalorieLimit < 0) {
throw new NegativeNumberException();
}

if (gender != 'M' && gender != 'F') {
throw new WrongGenderException();
}

Height heightData = new Height(height);
Weight weightData = new Weight(weight);
Calories caloriesData = new Calories(dailyCalorieLimit);
Gender genderData = new Gender(gender);

return new UserProfile(heightData, weightData, caloriesData);
return new UserProfile(heightData, weightData, caloriesData, genderData);
} catch (java.lang.NumberFormatException e) {
throw new NumberFormatException();
} catch (WrongGenderException e) {
throw new RuntimeException(e);
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/fittrack/parser/WrongGenderException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package fittrack.parser;

public class WrongGenderException extends ParseException {
}
9 changes: 8 additions & 1 deletion src/main/java/fittrack/storage/UserProfileDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import fittrack.UserProfile;
import fittrack.data.Calories;
import fittrack.data.Gender;
import fittrack.data.Height;
import fittrack.data.Weight;
import fittrack.parser.IllegalValueException;
Expand All @@ -18,6 +19,9 @@ public class UserProfileDecoder {
private static final Pattern WEIGHT_PATTERN = Pattern.compile(
"Weight:\\s+(?<weight>\\S+)kg"
);
private static final Pattern GENDER_PATTERN = Pattern.compile(
"Gender:\\s+(?<gender>\\S+)"
);
private static final Pattern CALORIES_PATTERN = Pattern.compile(
"Daily calorie limit: (?<calLimit>\\S+)kcal"
);
Expand All @@ -37,6 +41,7 @@ public static UserProfile decodeUserProfile(List<String> encodedUserProfile)
final Matcher heightMatcher = HEIGHT_PATTERN.matcher(decodedUserProfile[0]);
final Matcher weightMatcher = WEIGHT_PATTERN.matcher(decodedUserProfile[1]);
final Matcher caloriesMatcher = CALORIES_PATTERN.matcher(decodedUserProfile[2]);
final Matcher genderMatcher = GENDER_PATTERN.matcher(decodedUserProfile[3]);

if (!heightMatcher.matches() || !weightMatcher.matches()
|| !caloriesMatcher.matches()) {
Expand All @@ -47,11 +52,13 @@ public static UserProfile decodeUserProfile(List<String> encodedUserProfile)
final double height = Double.parseDouble(heightMatcher.group("height"));
final double weight = Double.parseDouble(weightMatcher.group("weight"));
final double dailyCalorieLimit = Double.parseDouble(caloriesMatcher.group("calLimit"));
final char gender = genderMatcher.group("gender").charAt(0);

Height heightData = new Height(height);
Weight weightData = new Weight(weight);
Calories caloriesData = new Calories(dailyCalorieLimit);
Gender genderData = new Gender(gender);

return new UserProfile(heightData, weightData, caloriesData);
return new UserProfile(heightData, weightData, caloriesData, genderData);
}
}
2 changes: 1 addition & 1 deletion src/test/java/fittrack/command/EditProfileCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void getHelpReturnsCorrectHelpMessage() {
EditProfileCommand editProfileCommand = new EditProfileCommand(EditProfileCommand.COMMAND_WORD);

String expectedHelpMessage = "`editprofile` allows you to edit your profile." +
"\nType `editprofile h/<HEIGHT> w/<WEIGHT> l/<CALORIE_LIMIT>` to edit.";
"\nType `editprofile h/<HEIGHT> w/<WEIGHT> g/<GENDER> l/<CALORIE_LIMIT>` to edit.";

String actualHelpMessage = editProfileCommand.getHelp();

Expand Down
21 changes: 11 additions & 10 deletions src/test/java/fittrack/parser/CommandParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,12 @@ void getInvalidCommandCommandResult_foo_foo() {
@Test
void parseProfile_h180w80l2000_success() {
try {
UserProfile profile = new CommandParser().parseProfile("h/180 w/80 l/2000");
UserProfile profile = new CommandParser().parseProfile("h/180 w/80 g/M l/2000");
assertEquals(180.0, profile.getHeight().value);
assertEquals(80.0, profile.getWeight().value);
assertEquals('M', profile.getGender().getGender());
assertEquals(2000.0, profile.getDailyCalorieLimit().value);
} catch (PatternMatchFailException | NegativeNumberException | NumberFormatException e) {
} catch (PatternMatchFailException | NegativeNumberException | NumberFormatException | WrongGenderException e) {
throw new RuntimeException(e);
}
}
Expand All @@ -143,14 +144,14 @@ void parseProfile_h180w80l2000_success() {
void parseProfile_fail() {
CommandParser parser = new CommandParser();
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile(""));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/ w/ l/"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/180 w/80 l/"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/ w/80 l/2000"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/180 80 2000"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("180 w/80 l/2000"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("180 80 2000"));
assertThrows(NumberFormatException.class, () -> parser.parseProfile("h/180 w/eighty l/2000"));
assertThrows(NegativeNumberException.class, () -> parser.parseProfile("h/-180 w/80 l/2000"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/ w/ g/ l/"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/180 w/80 g/ l/"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/ w/80 g/ l/2000"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("h/180 80 M 2000"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("180 w/80 g/M l/2000"));
assertThrows(PatternMatchFailException.class, () -> parser.parseProfile("180 80 M 2000"));
assertThrows(NumberFormatException.class, () -> parser.parseProfile("h/180 w/eighty g/M l/2000"));
assertThrows(NegativeNumberException.class, () -> parser.parseProfile("h/-180 w/80 g/M l/2000"));
}

@Test
Expand Down
Loading

0 comments on commit 42da67b

Please sign in to comment.