PROJECT: FitBiz

Overview

FitBiz is a desktop fitness business management application. It keeps track of the user’s schedule. It can record the user’s client information such as basic data like their names, phone numbers, addresses etc. On top of that, it also records data useful to gym coaches, such as the clients' exercise logs, personal bests. FitBiz also features graph visualisation for gym coaches to obtain a visual progress indicator for the client’s exercises, and is customisable to some extent by the user. The user interacts with FitBiz via a Command Line Interface(CLI).

Summary of contributions

  • Major enhancement: added Schedule feature and its commands

    • What it does: allows the user to add weekly training schedules to their clients. All schedules are consolidated from across all the clients and represented into a sorted weekly Schedule Panel on the right of the main GUI for easy reference. The command for Schedule is:

      • schedule INDEX sch/DAY-STARTTIME-ENDTIME

        Users will be able to clear, or overwrite multiple schedules to the specified client.

    • Justification: This feature improves the product significantly because enabling a scheduling system is an integral functionality for gym coaches to manage multiple clients, each with varying time slots and schedules.

    • Highlights: The schedule feature is an important building block to be built upon for future releases. Future features such as training results prediction would require analysis of the schedule to perform calculations on a Client’s predicted performance by the end of say, 6 months down the road, which ties in deeply with the other features of FitBiz such as the Exercise component. Furthermore, it can also potentially be paired with the Graph feature to visually display predicted trainings.

  • Major enhancement: implemented the SchedulePanel in the MainWindow of the GUI to represent the weekly schedule

    • What it does: Schedules are shown neatly and in a sorted manner for the week.

    • Justification: For FitBiz to be more intuitive and convenient for the user, the main GUI displays the weekly schedule on the right to provide easy access for the user to view his clients' schedules, instead of having to rely on text outputs for schedule without a GUI.

    • Highlights: This enhancement requires knowledge of working with JavaFX. Furthermore, with SchedulePanel being a part of a larger GUI, I learnt to work under the constraints of the environment, as well as integrate my GUI feature as part of a larger project.

      • The Schedule Panel models a weekly schedule, thus there would be seven days of the week to represent. To achieve this, I implemented a SchedulePanel class that constructs seven ScheduleCell, each ScheduleCell representing a day of the week

      • Each ScheduleCell takes in a sorted ObservableList of Schedule which it uses to display the schedules for the day within the cell. I chose ObservableList to make use of the Observer Pattern taught in CS2103, where SchedulePanel would be subscribed to changes in the ObservableList, so that I can ensure information shown in SchedulePanel correctly reflects the updated schedules, whether schedules have changed or even if Clients with schedules have been removed.

      • As each day could contain vastly different amounts of schedules, having a fixed ScheduleCell size for each day would be inflexible and potentially buggy, unless I choose to truncate Schedules, which would defeat the purpose of the Schedule Panel. Hence, I implemented ScheduleCell to expand its cell size vertically downwards dynamically according to the amount of schedules on that day. This way, days without schedule can have their respective ScheduleCell kept minimal, whilst even days with many schedules (over 100+ schedules tested) can well display the schedules.

  • Minor enhancement: refactored Person from AddressBook to Client to fit the requirements of FitBiz

  • Minor enhancement: added Birthday attribute to Client, making use of LocalDate and also sanity checks to ensure that the client does not enter a birthday too old, i.e. 120 years. According to Wikipedia as of this PPP, the oldest living person in the world today is 117.

  • Code contributed: RepoSense

  • Other contributions:

    • Enhancements to existing features:

      • Wrote test code for schedule classes and commands, and birthday tests to improve test coverage: 142, 44

      • Helped to add sanity check for ExerciseDate: 225

    • Documentation:

      • Wrote the implementation of schedule command in Developer Guide, as well as the GUI implementation for Schedule: 127, 142

      • Wrote the command guide for list-c, edit-c and schedule in User Guide: 259,

      • Changed Model and Storage diagrams of Developer Guide: 259,

    • Community:

      • PRs reviewed: 283, 223, 136

      • Reported bugs and suggestions for other teams in the class: 245, 244, 243, 242, 241, 240

      • Discussed and squashed bugs with non-trivial implementations: 236, 207,

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.

Edit a client’s profile: edit-c ---Ng Ming Liang

edit-c allows you to edit an existing client’s details from the Client List. There are various attributes that can be edited for the client using this command, which will be covered in this section.

Format: edit-c INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [g/GENDER] [b/BIRTHDAY] [cw/CURRENT_WEIGHT] [tw/TARGET_WEIGHT] [h/HEIGHT] [s/SPORT]…​ [t/TAG]…​ [r/REMARK]

Parameters

This section acts as a summary of the important things to note when using edit-c and its parameters. The square bracket shows that it is optional and your command will still execute even if you do not enter them. However, at least one of them have to be specified. The ellipsis after a parameter …​ means that there can be multiple of that same type of parameter.

Parameters Important points to note

INDEX

* Substitute INDEX with the index of the desired client to edit.

* INDEX is compulsory and you have to specify it.

* INDEX must be a positive number, and must be a valid index number for a client as displayed from the list of clients.

[n/NAME]

* Substitute NAME with the name of the client.

* NAME should only contain alphanumeric characters, spaces and commas, and it should not be blank.

* NAME is optional.

[p/PHONE]

* Substitute PHONE with the phone number of the client.

* PHONE should only contain numbers.

* PHONE should be at least 3 digits long.

* PHONE is optional.

[e/EMAIL]

* Substitute EMAIL with the email of the client.

* EMAIL should be of the format xxx@yyy, where:

* xxx should only contain alphanumeric characters and the set of special characters* shown below this table

* yyy must be at least 2 characters long, start and end with alphanumeric characters, and consist of alphanumeric characters, a period or a hyphen for the characters in between, if any.

* EMAIL is optional.

[a/ADDRESS]

* Substitute ADDRESS as the address of the client.

* ADDRESS can take any value, but it should not be blank, or start with a whitespace.

* ADDRESS is optional.

[g/GENDER]

* Substitue GENDER with the gender of the client.

* GENDER is case insensitive

* GENDER can only be male or m, female or f, or others or o.

* GENDER is optional.

[b/BIRTHDAY]

* Substitue BIRTHDAY with the birthday of the client.

* BIRTHDAY should be in the format DD-MM-YYYY

* BIRTHDAY cannot exceed the current date.

* BIRTHDAY cannot be earlier than 120 years from the current year.

* BIRTHDAY is optional.

[cw/CURRENT_WEIGHT]

* Substitute CURRENT_WEIGHT with the current weight of the client.

* CURRENT_WEIGHT must take the value of a whole or decimal number(eg. 65 or 86.22)

* CURRENT_WEIGHT can only have a maximum of 3 digits before the decimal place and a maximum of 2 digits after the decimal place (eg. 101.25 or 120.20)

* CURRENT_WEIGHT is optional.

[tw/TARGET_WEIGHT]

* Substitute TARGET_WEIGHT with the target weight for the client.

* TARGET_WEIGHT must take the value of a whole or decimal number(eg. 65 or 86.22)

* TARGET_WEIGHT can only have a maximum of 3 digits before the decimal place and a maximum of 2 digits after the decimal place (eg. 101.25 or 120.20)

* TARGET_WEIGHT is optional.

[h/HEIGHT]

* Substitue HEIGHT with the height of the client.

* HEIGHT must either be a whole or decimal number.

* HEIGHT can only have a maximum of 3 digits before the decimal place and a maximum of 2 digits after the decimal place (eg. 101.25 or 120.20)

* HEIGHT is optional.

[s/SPORT]

* Substitute SPORT with the sports of the client.

* SPORT should only contain alphanumeric characters and spaces.

* Sports given in this command will overwrite all of the client’s existing sports.

* SPORT is optional.

[t/TAG]

* Substitue TAG with a tag for the client.

* TAG should only contain alphanumeric characters.

* Tags given in the command will overwrite the Client’s existing tags

* You can remove all of the client’s tags by typing t/ without specifying any TAG

* TAG is optional.

[r/REMARK]

* Substitute REMARK with remarks for the client.

* REMARK should be alphanumeric.

* Any whitespace at the start of REMARK will be removed.

* REMARK is optional.

*The set of special characters are !#$%&'*+/=?{|}~^.-`

At least one of the optional fields must be provided.

Example

Let’s say you want to edit the address and assign 3 sports (Tennis, Hockey, Badminton) to client Irfan Ibrahim. From the Client List, you can see that his client INDEX is 3.

UGEditCDiagram1

Next, you can enter the command edit-c 3 a/New Address #123456 s/Tennis s/Hockey s/Badminton in the Command Box.

UGEditCDiagram2

Enter the command, and you should see that the Result Box displays the edited client’s information, and that the Client List has updated Irfan Ibrahim to show the new changes.

UGEditCDiagram3

Common Errors/Problems

You might face some errors or difficulties when you use edit-e. In this section, you will be able to understand these errors and resolve them.

Result box not displaying updated client’s information

When you use edit-c, instead of seeing the updated client’s information in the Result Box, you might sometimes encounter an error message informing you about the specifications for the format of the command. This error message varies according to the mistake detected in the parameters given. For simplicity, let’s look at one example scenario.

Let’s say you attempt to edit the email of Irfan Ibrahim and happen to give an incorrect format of the email that does not follow the rules given in the parameters table above for EMAIL. Consider the following command: edit-c 3 e/invalidEmail.

UGEditCDiagram4

As seen above, the EMAIL is of the wrong format as it does not include the @ symbol and not of the xxx@yyy format.

In the example above, the EMAIL field was faulty. This behaviour of FitBiz also applies to other faulty parameters for the edit-c command, where FitBiz will display information relevant to the faulty parameter, to help you troubleshoot and correct your input.

Schedule trainings for a client: schedule ---Ng Ming Liang

Schedule allows you to assign weekly schedule timings to a client. The schedule will be displayed on the right panel of FitBiz, with the timings as well as the client’s name. You can assign multiple schedules to a client at once, by adding more arguments following the command. All of the schedules from the current Client List will be displayed on the Schedule Panel.

Format: schedule INDEX sch/DAY-STARTTIME-ENDTIME [sch/DAY-STARTTIME-ENDTIME]…​

The schedule command overwrites the client’s existing schedule with the new schedules given in the command.

Parameters

This section acts as a summary of the important things to note when using schedule. The square bracket shows that it is optional and your command will still execute even if you do not enter them.

Parameters Important points to note

INDEX

* Substitute INDEX with the index of the desired client to add the schedule to.

* INDEX is compulsory and you have to specify it.

* INDEX must be a positive number, and must be a valid index number for a client as displayed from the list of clients.

DAY

* Substitute DAY with the first three letters of the day.
eg. MON / TUE / WED / THU / FRI / SAT / SUN

* DAY is compulsory and you have to specify it.

* DAY can only be one of the above seven values.

* DAY is not case sensitive.

STARTTIME

* Substitute STARTTIME with the starting time of the schedule slot.

* STARTTIME is compulsory.

* Range for STARTTIME is 0000-2359.

* STARTTIME must always be earlier than or equal to ENDTIME.

ENDTIME

* Substitute ENDTIME with the ending time of the schedule slot.

* ENDTIME is compulsory.

* Range for ENDTIME is 0000-2359.

* ENDTIME must always be equal to or later than STARTTIME.

Example

Let’s say you want to schedule a weekly Monday 11:00am to 12:00pm slot for your client Alex Yeoh. Alex Yeoh is the first client on your Client List.

UGScheduleDiagram1

You can see that Alex Yeoh’s client index is 1. Therefore, you can proceed to type the schedule command in the Command Box to assign a schedule slot to him.

UGScheduleDiagram2

After you enter the command, you can see that the Result Box has notified you of the new overwritten schedule, and that Alex Yeoh’s schedule slot has appeared on the Schedule Panel on Monday.

UGScheduleDiagram3

Now let’s say you want to add multiple schedules to Bernice Yu: Monday 8:00am to 10:00pm and Tuesday 4:00pm to 6:00pm. You can do that by adding both of these timings into the schedule command following the same format as above.

UGScheduleDiagram4

Now enter the command, and you’ll see that Bernice’s schedules also show up on the Schedule Panel.

UGScheduleDiagram5

Finally, let’s say Alex no longer has any schedule slots, and you want to clear it. Simply type in schedule 1 sch/ in the Command Box to clear his schedule, and you should see this.

UGScheduleDiagram6

Common Errors/Problems

You might face some errors or difficulties when you use schedule. In this section, you will be able to understand these errors and resolve them.

Overlapping schedules

You might encounter the message that "One or more of your input schedules have overlapping time periods. Please check again." This means that there is a overlapping time period between at least two of your input schedules. In this case as shown below, the first schedule sch/MON-1100-1200 conflicts with the second schedule sch/MON-1200-1300 because the end time of the first schedule overlaps with the start time of the second schedule.

UGScheduleDiagram7
Overlapping schedules are not allowed between schedules within the same client. However, different clients can have overlapping schedules with each other as it is a possible scenario that you as a gym coach can coach multiple clients at once, and that additional clients can join/leave the session as other sessions are ongoing.

Invalid command format

You might encounter the error message from the Result Box specifying the format that you should be using for the schedule command. This means that there are one or more errors in the format of your input for the schedule command. In the example input shown below, schedule 2 sch/TUESDAY-800-1:00, there are multiple errors. First, the DAY should be three letters. Next, the STARTTIME and ENDTIME should follow the HHmm format. The correct input for this should be schedule 2 sch/TUE-0800-1300.

UGScheduleDiagram8

List all clients: list-c ---Ng Ming Liang

You can list all clients on the Client List. This is useful when your Client List has been filtered by the filter-c command, and you want to view all clients again. When using list-c, there will be no difference to the Client List if it is already showing all clients.

Format: list-c

Parameters

The command is simply list-c, and has no additional parameters.

Example

Let’s say you start off with the full Client List as shown below.

UGListCDiagram0

Now, let’s say you use the command filter-c to filter the clients with the Paleo tag as such:

UGListCDiagram2

Your Client List will now display only the clients that have the Paleo tag. In this example, the only client that fit this requirement is Alex Yeoh.

UGListCDiagram3

Let’s say you are done with the filter, and want to list all your clients on the Client List again. Simply enter `list-c`into the Command Box and you should be able to see the following:

UGListCDiagram4

Common errors / problems

No clients shown on the Client List

You may be greeted with the following scene. This means that there are no clients in your FitBiz. You can begin adding clients by using the add-c command. Do refer to the add-c section in this document for help regarding add-c.

UGListCDiagram5

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.

Model component

ModelClassDiagram
Figure 1. Structure of the Model Component

API : Model.java

The Model,

  1. stores a UserPref object that represents the user’s preferences

  2. stores a ClientInView to represent the current selected Client selected by the view-c command

  3. stores FitBiz

  4. stores Client, Sports, Tag, Schedule and Exercise packages, where Client utilises the latter packages as attributes

  5. exposes an unmodifiable ObservableList<Client> that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change.

As a more OOP model, we can choose to store a Tag list in FitBiz, which Client can reference. This would allow FitBiz to only require one Tag object per unique Tag, instead of each Client needing their own Tag object. An example of how such a model may look like is given below. For simplicity, we have omitted the rest of the attributes that Client has. Refer back to the diagram above for more details.

BetterModelClassDiagram

Scheduling for a Client --- Ng Ming Liang

This feature allows for a user to assign a weekly schedule to a client. Timings are represented in the 24-hour format HHmm. Each client can have none or multiple schedules that do not have overlapping timings. Multiple clients are allowed to have overlapping timings with each other.

Implementation

This scheduling mechanism is facilitated by ScheduleCommand which extends Command. The format of the command is given by:

schedule INDEX sch/DAY-STARTTIME-ENDTIME [sch/DAY-STARTTIME-ENDTIME] …​

When using this command, at least one valid complete schedule parameter must be specified. The user can follow up with additional optional valid schedule parameters in order to assign more schedules to the same client. The following 3 examples are all valid usages of the schedule command:

Example Commands

  1. schedule 1 sch/MON-1100-1300

  2. schedule 2 sch/MON-1100-1300 sch/TUE-1100-1300 sch/SAT-1800-2000

  3. schedule 3 sch/

Elaboration on Example Commands

  1. This command instance schedules Client with index 1 to have a schedule slot on every Monday, 11:00am to 1:00pm.

  2. This command instance schedules Client with index 2 to have schedule slots on every Monday 11:00am to 1:00pm, Tuesday 11:00am to 1:00pm, and Saturday 6:00pm to 8:00pm.

  3. This command instance schedules Client with index 3 to have no schedule slots, that is essentially clearing the schedule of Client with index 3. The sch/ parameter is required when clearing the schedule.

Do note that the schedule parameters given in the schedule command will entirely overwrite the client’s current list of schedules.

The list of schedules of each client are structured as a ScheduleList, which is a wrapper class for an ArrayList of Schedule objects. Each Client contains one ScheduleList attribute to keep track of all Schedule assigned to it. If there are no assigned Schedule for the Client, then the ScheduleList simply contains an empty ArrayList of Schedule.

Schedule comprises three attributes:

  1. Day

  2. StartTime

  3. EndTime

Day wraps the enum DayEnum.Weekday and represents the day of the week the schedule takes place on.

StartTime and EndTime represent the start time and end time of the schedule in the "HHmm" format respectively.

The relations between these classes are shown in the class diagram below.

ScheduleClassDiagram

These attributes are bounded by these characteristics:

  1. Each Client can only contain unique Schedule, that is, there are no overlaps in timings between any two Schedule in the ScheduleList. This is ensured by ScheduleCommandParser#checkIfOverlaps()

  2. Overlapping timings between the Schedule of different Client is allowed

  3. The maximum timeframe between StartTime and EndTime is from 0000 to 2359

  4. StartTime cannot be later than EndTime

  5. Day can only take up the 7 values of the week (MON/TUE/WED/THU/FRI/SAT/SUN)

Here is an activity diagram displaying the steps taken when FitBiz receives a user input for the schedule command:

ScheduleActivityDiagram

In the following sequence diagram, we trace the execution for when the user decides to enter the command schedule 1 day/mon st/1100 et/1200 into FitBiz. For simplicity, we will refer to this command input as commandText:

ScheduleSequenceDiagram

This sequence diagram shows how the schedule command is processed in FitBiz. The LogicManager receives the input commandText and parses it with FitBizParser to obtain arguments that are then parsed into ScheduleCommandParser to construct a ScheduleCommand. This ScheduleCommand is returned back up to the LogicManager which then executes it with reference to the model argument. Subsequently, the Model is updated with a new Client with the schedule changes through a series of commands as shown in the right hand side of the sequence diagram, and control is return back to LogicManager.

Design Considerations

In designing this feature, we had to consider the alternative ways in which we can choose to store the information of a schedule. One option of storing the relevant information (day, start, end times) for a schedule was simply to concatenate these values into a single String, for example, monday-1100-1200. However, we found that this did not exploit the desirable principles of Object-Oriented Programming. As respective sanity checks had to be done for the day and timing, wrapping each of these properties into their wrapper classes allowed for better modularity and organisation of these attributes. For example, Day#isValidDay handles the validation of the input for day and Time#isValidTimingFormat handles the validation of time.

Considerations also then had to be made for how to contain multiple Schedule. The current implementation uses the ArrayList data structure to hold multiple Schedule. Other considered alternative for ScheduleList was HashSet.

ArrayList HashSet

Ensuring no overlaps

Does not ensure that its elements are unique

Ensures no duplicate values

Ensuring order of elements

Elements can be sorted and retrieved in ascending order

Does not return elements in order

Displaying the Schedule Panel

The schedules of all the clients are displayed in a time-sorted manner on the SchedulePanel of the main FitBiz GUI as shown in the picture below, demarcated by the red rectangle:

SchedulePanelGUIExample

The SchedulePanel extends UiPart<Region> and takes in a ScheduleDay class. ScheduleDay is similar to ScheduleList, the difference being:

  • ScheduleDay wraps an ArrayList of Schedule for a specific Day

  • ScheduleList wraps an ArrayList of Schedule for a specific Client

As the nature of the SchedulePanel was to display a sorted collection of Schedule, we chose ArrayList as the underlying data structure, due to the ability to sort the ArrayList via a comparator that compares Schedule according to their Day and StartTime. The code snippet below shows how the Schedule are being sorted using an anonymous comparator in the constructor for ScheduleDay:

this.scheduleList.sort(Comparator.comparingInt(o -> o.getStartTime().getDirectTimeInt()));

In addition, we also harnessed the capability of the HashSet to ensure no overlaps between Schedule within each Client, which is implemented by ScheduleCommandParser#checkIfOverlaps. As the ArrayList of Schedule is being populated in the constructor of ScheduleDay, we used a HashSet to check for any overlapping Schedule. The equals method of Schedule was overriden to consider overlapping timeframes between StartTime and EndTime to be equal.