Overview
My team of 4 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 has statistical analysis of exercises 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:
//TODO: Add image of UI
Summary of contributions
-
Major enhancement: added the ability to search for suggestions
-
What it does: The command
suggest
allows the user to search for suggestions. -
Justification: This feature enables new users to have a starting point in their exercise regime. This feature also offers experienced users suggestions based on the type of exercises the user wants to do.
-
Highlights: This enhancement works well with existing features, such as Custom Properties, and can be expanded on. It required an in-depth analysis of design alternatives to ensure that future extensions or further enhancements can be smooth. The implementation too was 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.
-
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.
-
Code contributed: [Functional code] [Test code] {give links to collated code files}
-
Other contributions:
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
Suggest basic exercises
Recommends exercises from ExerHealth’s inbuilt database for beginners.
Format: suggest s/basic
Suggest 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/02/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:

The input, suggest s/possible o/or m/Chest r/8
, however, will display a list of exercises with "Chest" or have a rating of 8.

Expected Result:

As seen on the image above, the two previously added exercises named "Bench Press" and "Run" are displayed because they each have a rating of 8. In addition to the tracked exercises, ExerHealth will also display suggestions in its database. Hence the exercise named "Push Ups" is displayed as it has a "Chest" muscle tag.
Duplicates
Sometimes, you may track exercises of the same name. Instead of displaying all suggestions of the same name, this function display the information of the most recently tracked exercise of that name.

Expected Result:

As seen on the image above, the tracked exercise named "Bench Press" on "06/11/2019" is displayed instead of the one on "05/11/2019".
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 and may be overwhelmed when 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 other hand, regular gym goers may face a repetitive and mundane exercise routine or may want to experiment with different exercises. As such, 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. This 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 (Figure 21) summarizes what happens when a user enters a suggest possible command:

In detail, when a SuggestPossibleCommand
is entered, the Logic
component is responsible for parsing the inputs into a Predicate
.
The Predicate
is then used to instantiate a SuggestPossibleCommand
, 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 (Figure 22) shows the sequence flow from the when a user enters a valid SuggestPossibleCommand
:

From the sequence diagram:
-
When the
LogicManager
receive theexecute
command, it calls theparseCommand
method ofExerciseBookParser
. -
ExerciseBookParser
will receivesuggest
as the command type and instantiateSuggestCommandParser
to further parse the command. -
SuggestCommandParser
will receives/possible
as the suggest type and calls theparsePredicate
method ofParserUtil
to parse the user input to create anExercisePredicate
object (namedp
in the diagram). -
SuggestCommandParser
will instantiateSuggestPossibleCommand
with theExercisePredicate
as the constructor parameter. -
The
SuggestPossibleCommand
object is then returned toSuggestCommandParser
,ExerciseBookParser
and lastly back toLogicManager
to execute. -
LogicManager
will proceed to call executeSuggestPossibleCommand
. -
SuggestPossibleCommand
then calls theupdateSuggestedExerciseList
method inModelManager
, passing in the predicate to filter the list of suggest exercises. -
SuggestPossibleCommand
creates a newCommandResult
to be returned.
In step 3, the process in which the ExercisePredicate
object is created can be explored deeper (Figure 23).

ExercisePredicate
is createdFrom the sequence diagram above:
-
ParserUtil
createsExerciseMusclePredicate
andExerciseCustomPropertyPredicate
with the input parameters. -
Since there were no CustomProperty tags to filter,
ParserUtil
createsExercisePredicate
with only themusclesPredicate
and the booleanisStrict
. -
The resulting
ExercisePredicate
is then returned toParserUtil
and thenSuggestCommandParser
.
The diagram below shows the structure of a ExercisePredicate
object.
A ExercisePredicate
contains a list
of BasePropertyPredicate
,
where each contains a Collection
of Muscle
or CustomProperty
.

Creating classes such as ExerciseCustomPropertyPredicate
and ExerciseMusclePredicate
allow us to conduct better testing because we can compare the Collection
of Muscle
/CustomProperty
being considered.
Design Considerations
Aspect: Implementation of predicate creation
-
Choice 1:
SuggestPossibleCommand
to handle the predicates.-
Pros:
-
Easy to implement and understand. The class
SuggestPossibleCommand
contains 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 SRP as
SuggestPossibleCommand
, in addition to updating the model, has to create the predicate.
-
-
-
Choice 2 (current choice): Predicate class to handle all predicates.
-
Pros:
-
Adheres to Single Responsibility Principle (SRP) and Separation of Concern (SoC).
-
-
Cons:
-
Increases the complexity of the code as more classes are needed, also increasing the lines of code written.
-
-
PROJECT: PowerPointLabs
{Optionally, you may include other projects in your portfolio.}