PROJECT: ZeroToOne

Overview

ZeroToOne is a desktop application that serves as an all-in-one exercise tracker and personal aide. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 26 kLoC.

Summary of contributions

  • Major enhancement: added the Workout Session Feature

    • What it does: Allows the user to start a workout session by providing a WORKOUT_ID. The session keeps track of the user’s workout by providing a queue of upcoming sets and the progress of the previous set. The session also includes a rest timer that helps users keep to their workout schedule between sets.

    • Justification: This feature is a core feature within the app. It helps users keep to their workouts and ensures that even the most tired user will not forget any exercise during a workout session.

    • Highlights: This feature required major design consideration in order to maintain a bug-free, stateful representation of a workout session, with a user-facing experience that automatically logs completed sessions.

  • Major enhancement: added the Rest Timer Feature

    • What it does: Seamlessly integrated with the Workout Session Feature, the timer helps users keep to their workout schedule and times rest between sets.

    • Justification: Helps users manage their workout session and keep to their rest time for an optimal workout.

    • Highlights: This feature requires the use of a thread to update the clock. Major design consideration was required to ensure that the timer was not computationally expensive yet reliable, and that the feature was user-facing and integrated with the session feature seamlessly.

  • Code contributed:

Feature Component Functional Code Test Code

Session feature

Commands (Start, Stop, Skip, Done)

github folder

github folder

Parsers

github folder

github folder

Models (Ongoing- prefixed)

github folder

github folder

Ui

github folder

NA

FXML

github folder

NA

Timer feature

Found in ModelManager

github file

NA


  • Other contributions:

    • Project management:

      • Organised and managed weekly team meetings including taking minutes on google docs.

      • Facilitated task delegation at the inception of the tP.

    • Enhancements to existing features:

      • Edit GUI for overall cohesiveness (Pull requests #213, #219)

      • Disabled non session related commands during a session for more predictable app behaviour (no editing of workouts during workout) (Pull requests #187)

    • Documentation:

      • Add documentation coverage for the entire workout session feature including diagrams. #110

      • Edit Model Component diagram. #238

      • Update all screenshots in user guide. #241

      • Add DG Appendix F and G. #244, #254

    • Review Contributions:

      • PRs reviewed (with non-trivial review comments): #66, #114

      • Total PRs reviewed: 21+

    • Community:

      • Reviewed other teams documentation: #29

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.

Starting A Workout Session [Gabriel Yeo]

Are you ready to start working out now? To begin a new workout session, simply enter the following command into the command box:

start WORKOUT_ID
Example use:
start 1
UgStartWorkout
Figure 1. Started Workout

The User Interface will automatically switch to the “Home” tab. ZeroToOne will display upcoming sets in your workout, guiding you through set by set in your workout.

NOTE:
* This command assumes that you have already created a workout in the application. If you have not, refer to the section on "Managing your workouts" to create a new workout.
* WORKOUT_ID cannot be null and should be a value of a workout from the workout tab.

Completing a Set [Gabriel Yeo]

Completed your exercise set? To mark the current exercise set as complete and move on to the next set, simply enter this command into the command box:

done
UgDoneSet
Figure 2. Done Set

The background color of the completed set will turn green, indicating that the set is successfully completed. ZeroToOne will then progress your workout forward, indicating your next set. Additionally, the timer will reset to 00:00 and begin counting your rest for you.

After however many seconds you wish to rest, you may continue on to your next set.

If you were already on your last set, ZeroToOne will automatically stop the workout session after this command is executed and save your session to the Log.

Skipping An Exercise Set [Gabriel Yeo]

Unable to complete your current exercise set? No worries, it happens to the best of us. To skip the current exercise set, simply enter this command into the command box:

skip
UgSkippedSet
Figure 3. Skipped Set

The background color of the completed set will turn red, indicating that the set is incomplete.

This action is otherwise identical to the done command.

Stopping A Workout Session [Gabriel Yeo]

Need to stop the workout session prematurely? Simply enter this command into the command box:

stop

ZeroToOne will stop the workout that is currently in progress, and save the session into the Log. All remaining sets are marked as incomplete. The user interface will automatically return to the main screen. If stopping a workout session is successful, you should see the following in the feedback display with your workout name and time:

Stopped workout session: Push Day at 13 Apr 2020, 3:36:17 PM

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.

Session (Home) [Gabriel Yeo]

Implementation

The Session feature resides on the Home page and is comprised of Start, Stop, Done, and Skip commands. OngoingWorkout, OngoingSession, OngoingSet, and OngoingSetList are models that are vital components of the feature.

The Session feature also seamlessly incorporates a functional timer. Timer functionality is found embedded in the session related functions in ModelManager.

The activity diagram below demonstrates the actions of a user with this feature.

StartStopActivityDiagram
Figure 4. Session Feature Activity Diagram

Start depicts the start of a valid (non-zero sets remaining) workout session. Upon depletion of all remaining sets, the OngoingWorkout automatically stops and produces a CompletedWorkout which is saved. The only inputs the user is required to give throughout the session are done (corresponding to the yes of the conditional branch) and skip (no of the conditional branch). Stop is optional.

This is a conscious design choice as elaborated in the next section.


The operations handling these actions are found in OngoingWorkout:

  • OngoingWorkout#skip()/OngoingWorkout#done() — removes and returns the next set and updates queue of remaining sets.

  • OngoingWorkout#finish() — creates and returns an immutable CompletedWorkout object for saving and logging.

Further operations are exposed in the Model interface as Model#startSession() and Model#stopSession().

SessionModel
Figure 5. Session related models

The above class diagram briefly depicts how the session related models (in OngoingWorkout) interact with surrounding classes.

The OngoingWorkout class has a dependency on Workout, which has been abstracted for clarity.

In turn, CompletedWorkout class has a dependency on OngoingWorkout.

OngoingWorkout objects are created at the start of a workout session, and can be thought of as 'converted' to CompletedWorkout objects at the end of a workout session. Workout and CompletedWorkout objects are immutable, hence the design choice for using an intermediary, stateful OngoingWorkout class.


The inner workings of the feature are briefly expounded below through a simple simulation. Arms Day is a Workout with ID = 2 and consists of 2 sets of one exercise called Bench Press.

sessionExample
Figure 6. Example Workout Session

Step 1. The user selects an existing Workout called Arms Day with ID = 2 and starts a session with start 2.

  • Logic and Parser redirect control to StartCommand#execute() where an instance of OngoingWorkout is created with the Arms Day object. The upcoming set of the next exercise is displayed for the user.

  • The timer starts counting. This acts as a visual cue for the user that notifies the start of the workout and is essentially a once-off, superfluous action, since it’s main purpose is to time rest between sets.

Step 2. The user completes the first set and types done.

  • DoneCommand#execute() is invoked, which in turn calls Model#done() to obtain the last CompletedSet object to display on the UI, and statefully updates the instance of OngoingWorkout.

  • The rest timer resets to 00:00 and starts counting.

DoneCommandSequenceDiagram
Figure 7. DoneCommand sequence diagram
  • The sequence diagram above demonstrates the interaction between the Logic and Model of ZeroToOne. For brevity, some inner details between OngoingWorkout#done() and the return of cs are omitted.

Step 3. After resting, the user fails the last and final set of Bench Press and types skip.

  • SkipCommand#execute() is invoked. The process is almost identical to the above execution of done except this time the instance of CompletedSet is created with isFinished set to false.

  • Since this is the final set of the session, OngoingWorkout#hasSetLeft() returns false, and OngoingWorkout#finish() is called which creates and returns an immutable CompletedWorkout object. This object is saved and passed on for use by the Log feature.

  • The workout session is now complete, and the timer and UI is reset.

  • The workout session can be viewed in the Log tab.

[Note] In the usual flow, the stop command is not used, and is reserved only for a premature ending of a workout session, where all remaining sets are marked as incomplete.

Design Considerations

Aspect: Seamless user-first experience
  • Current Implementation: Minimal commands and typing during an ongoing session. Timer functionality is completely automatic.

    • Pros: Less interruption during actual exercising to enter commands.

    • Cons: More experienced users are not able to have a more customizable workout.

Aspect: Beginner-friendly set order
  • Current Implementation: Exercises and sets have fixed ordering based on their creation.

    • Pros: Easier for new user to follow a workout session, less typing required during a workout session. Session has simple and predictable behaviour.

    • Cons: Experienced users are not able to have an ad-hoc, customizable workout without creating a new workout with the specific order they want.

Appendix A: Effort [ZeroToOne Team]

Feature AB3 ZeroToOne

LoC

~10k

~26k

Difficulty

10

15

Effort

10

15

The idea of an exercise app alone itself is not particularly challenging. However, the ZeroToOne team believes that taking a user-experience-first philosophy toward designing an exercise app requires a conscientious design-approach, one that is a challenge.

This is something that we have endeavoured to achieve in this project.

We think that despite the constraints of the CS2103T project, we have managed to demonstrate this to a larger degree.

AB3 deals primarily in the domain of data storage and retrieval. ZeroToOne has taken this one step further, with the ability to:

  1. Statefully update new models during a workout session

  2. Apply useful statistics across an entire collection of stored data

  3. Extend AB3’s models to be more functional

Furthermore, on top of the ~16k LoC added to the project, the ZeroToOne team has managed to:

  1. Maintain > 70% test coverage

  2. Apply SOLID design principles

  3. Maintain a consistent quality of the codebase through stringent PR reviews and hooks.

The largest challenge we faced as a team was communication. Being fast-moving and driven individuals, taking the initiative sometimes meant being able to make decisions for the team as an individual. This meant that it was vital that we were on the same page with our goals and expectations from the project. Thus, we took more time than usual at the beginning of the project to plan our road-map moving forward, delegating work and defining our expectations clearly.

We hope you have enjoyed this journey and learnt as much as we have! - The ZeroToOne Team