Overview
My team of 5 computer science students were tasked with changing a basic command line application. Our team decided to morph the application into ExerHealth. ExerHealth is a desktop application used for tracking and scheduling the user’s exercises. The application contains statistical analysis of exercises that users have completed in the past. Additionally, it also acts as a personal trainer by suggesting different exercises which both beginners and advanced users can choose from to incorporate into their exercise regimes. The user interacts with it using a command line interface, and it has a GUI created with JavaFX.
Below is a screenshot of what our desktop application looks like:
Summary of contributions
-
Major enhancement: added the ability to search for suggestions
-
What it does: The command
suggestallows the user to search for suggestions. -
Justification: This feature gives new users a starting point in their exercise regime. This feature also offers experienced users suggestions based on the type of exercises the user wishes to do.
-
Highlights: This enhancement works well with existing features, such as Custom Properties, and can be expanded upon. It requires an in-depth analysis of design alternatives to ensure that future extensions or further enhancements can be smooth. The implementation was also challenging as it required multiple new predicate and utility classes.
-
-
Minor enhancement 1: Added the display panel on the left hand side of the UI to show the respective information after a command is executed (Pull request #121).
-
Minor enhancement 2: Allowed the command box to be automatically focused on upon opening the application so that user does not need to click on the box to start typing (Pull request #128).
-
Code contributed: RepoSense
-
Other contributions:
-
Project management:
-
Enhancements to existing features:
-
Refactored the GUI (Pull request #121)
-
-
Community:
-
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. |
Suggesting ideas: suggest
Suggests basic exercises
Recommends exercises from ExerHealth’s inbuilt database for beginners.
Format: suggest s/basic
Suggests possible exercises
Suggests exercises matching specified tags.
Based on matching muscle tags
Format: suggest s/possible o/OPERATION_TYPE [m/MUSCLE]… CUSTOM_PROPERTY_PREFIX_NAME/VALUE]…
Based on matching custom properties
Similar to matching muscles tags, you can search for suggestions with matching custom property tags.
After creating custom properties and tracking exercises, you can search for suggestions with those custom properties.
Example: Suppose you have created a new custom property and have been tracking a few exercises with said custom property:
-
custom s/r f/Rating p/Number -
add t/exercise n/Run d/03/11/2019 c/200 q/10 u/km m/Legs r/8 -
add t/exercise n/Bench Press d/05/11/2019 c/150 q/40 u/kg m/Chest r/8
Then, the following input will display a list of exercises which are tagged with Chest and have a rating of 8.
suggest s/possible o/and m/Chest r/8
Thus the command will display only the exercise named "Bench Press".
Expected Result:
Chest tag and a rating of 8 are shown.The input, suggest s/possible o/or m/Chest r/8, however, will display a list of exercises tagged with Chest or have a rating of 8.
Expected Result:
Chest tag and exercises with a rating of 8 are shown.As shown above, the two previously added exercises, "Bench Press and "Run", are displayed because they each have a rating of 8.
In addition to the tracked exercises, ExerHealth also displays suggestions in its database. Hence it will display the exercise named "Push Ups" as it has a Chest tag.
Duplicates
Sometimes, you may want to track exercises of the same name. Instead of displaying all suggestions of the same name, suggest
displays the information of the most recently tracked exercise of that name.
As can be seen below, there are two exercises named "Bench Press".
Expected Result:
Bench Press exercise is displayedAs seen from the image above, the information from the "Bench Press" on "06/11/2019" is displayed instead of the one on "05/11/2019" (observe that the calories are different).
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. |
Suggest
Rationale
Beginners now have a plethora of choices, which may overwhelm them when they are deciding on what exercises to do. Thus, we decided to provide users with sample exercise routines to reduce the inertia of starting this lifestyle change. On the other hand, regular gym goers may face a repetitive and mundane exercise routine or may want to experiment with different exercises. As such, to put it briefly, we decided to give users the ability to discover exercises based on the characteristics they are interested in.
This feature presents a cohesive function that all users can benefit from. It also makes our application well-rounded so that users can better achieve their fitness goals.
Overview
The sample exercise routines are currently implemented in ExerHealth’s database as a hard-coded set of exercises.
More importantly, the SuggestPossible command which caters to more experienced gym goers utilises the exercises that the user
has already done, in addition to ExerHealth’s database. Hence, we allow users to search for suggestions
based on Muscle and CustomProperty.
Current Implementation
The SuggestBasic command displays a list of exercises from our database to the user.
The SuggestPossible command is created by parsing the user’s inputs to form a Predicate before filtering ExerHealth’s database and the user’s tracked exercises.
The following activity diagram summarizes what happens when a user enters a SuggestPossible command:
SuggestPossible commandIn detail, when a SuggestPossible command is entered, the Logic component is responsible for parsing the inputs into a Predicate.
The Predicate is then used to instantiate a SuggestPossible command, and later used to filter a list of Exercise when the command is executed.
The interactions between the multiple objects can be captured using a sequence diagram.
The following sequence diagram shows the sequence flow when a user enters a valid SuggestPossible command:
SuggestPossibleCommand.From the sequence diagram:
-
When the
LogicManagerreceives theexecutecommand, it calls theparseCommandmethod ofExerciseBookParser. -
ExerciseBookParserwill receivesuggestas the command type and instantiateSuggestCommandParserto further parse the command. -
SuggestCommandParserwill receives/possibleas the suggest type and calls theparsePredicatemethod ofParserUtilto parse the user input to create anExercisePredicateobject (namedpin the diagram). -
SuggestCommandParserwill instantiateSuggestPossibleCommandwith theExercisePredicateas the constructor parameter. -
The
SuggestPossibleCommandobject is then returned toSuggestCommandParser, followed byExerciseBookParser, and lastly back toLogicManagerto execute. -
LogicManagerwill proceed toexecuteSuggestPossibleCommand. -
SuggestPossibleCommandthen calls theupdateSuggestedExerciseListmethod inModelManager, passing in the predicate to filter the list of suggest exercises. -
SuggestPossibleCommandcreates a newCommandResultto be returned.
In step 3, the process in which the ExercisePredicate object is created can be explored deeper.
ExercisePredicate is createdFrom the sequence diagram above:
-
ParserUtilcreatesExerciseMusclePredicateandExerciseCustomPropertyPredicatewith the input parameters. -
Since there were no CustomProperty tags to filter,
ParserUtilcreatesExercisePredicatewith only themusclesPredicateand the booleanisStrict. -
The resulting
ExercisePredicateis then returned toParserUtil, followed bySuggestCommandParser.
A SuggestPossibleCommand contains an ExercisePredicate object.
An ExercisePredicate object contains a list of BasePropertyPredicate,
where each contains either a Collection of Muscle or CustomProperty.
The diagram below shows the structure of a ExercisePredicate object.
Creating classes such as ExerciseCustomPropertyPredicate and ExerciseMusclePredicate
allows us to conduct better testing because we can compare the Collection of Muscle/CustomProperty between different predicates.
Design Considerations
Aspect: Implementation of predicate creation
-
Choice 1:
SuggestPossibleCommandto handle the predicates.-
Pros:
-
Easy to implement and understand. The class
SuggestPossibleCommandcontains the parsing and creation of the predicate all in one place as it stores the tags, and creates the predicate and filters the list of exercises.
-
-
Cons:
-
Violation of Single Responsibility Principle (SRP) as
SuggestPossibleCommandupdates the model and creates the predicate.
-
-
-
Choice 2 (current choice): Predicate class to handle all predicates.
-
Pros:
-
Adheres to SRP and Separation of Concern (SoC).
-
-
Cons:
-
Increases the complexity of the code as more classes are needed, and also increases the lines of code written.
-
-