PROJECT: Powerlifting Competition Coordinator

Overview

Powerlifting Competition Coordinator (PCC) is a desktop application for powerlifting event organizers. It maintains Athletes, Competitions, and Participations, as well as a live competition session handling for the main event.

Summary of contributions

  • Major enhancement 1: Added ability to handle competition sessions

    • What it does: Allows the user to start or resume a competition session, generate the next and following lifters/attempts in a pre-determined order, and update the success of the attempt accordingly.

    • Justification: This is one of the main features of PCC, to allow event organisers have a smooth flow of their competition event, and perform minimal functionality (under what it does) during the event.

    • Highlights:

      • This enhancement comes in many small parts: designing the Session component as a singleton class; creating appropriate dependencies to reduce coupling to main components such as Partipation or Attempt; adding the relevant commands for this session handling to work on the user-end.

      • It was challenging to implement as there are many different types of scenarios that can happen during a session, and i needed to handle it well with proper exception handling to ensure a smooth flow of the competition event. A deep understanding of the general flow of powerlifting competitions is necessary. Furthermore, since the main components need to be updated along with the session, it required an in-depth analysis of how the logic works with the model components.

      • Some concepts that i have learnt from CS2103 and have applied in this enhancement are: Single Responsibility Principle and Singleton Class.

  • Major enhancement 2: Added ability to CRUD Participation, the association class between Person and Competition.

    • What it does: Allows the user to create, read, update, and delete Participation-related information and objects. It includes some user-end commands such as creation of participations with a list of 9 attempts, list participation according to an existing competition, as well as deletion. Some other functions of this enhancement include the adding and updating of attempts, and also the tabulation of scores which is used in other contexts.

    • Justification: These commands allow the user to CRUD the association between a Person and Competition into a Participation. This is also an important feature so that the Participation can be properly prepared and updated before, during and after a competition session.

    • Highlights: For these features and commands on the user-end to work, the Participation association class and its dependencies need to be well set up, such that there is not too much coupling in the model.

  • Minor enhancement:

    • Added Participation List and Participation Cards to the GUI.

  • Code contributed: All code contributed

  • 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.

Commands related to managing persons participating in competitions will be introduced now.

Adding a new participation: addParticipation

Adds an existing person displayed in the Person list on the user interface into an existing competition displayed in the Competition list on the user interface. User also needs to supply 3 weight attempts for each of the following events:

  1. Squat

  2. Bench

  3. Deadlift

Format: addParticipation n/Athlete Name c/Competition Name s/S1/S2/S3 b/B1/B2/B3 d/D1/D2/D3

Example:

  • addParticipation n/Ho c/NUS 2022 s/100/101/102 b/300/400/500 d/1000/2000/3000

Note: S1 means the 1st attempted weight for the Squat and so on.

Listing all persons who are participating in all competitions or for one competition: listParticipation

Note that the user can choose to provide a competition name or not.

Format: listParticipation c/COMPETITION_NAME

Example: To display all persons for all competitions:

  • listParticipation

To display all persons for NUS 2022 competition only:

  • listParticipation c/NUS 2022

Deleting an existing participation: deleteParticipation

Deletes the participation identified by the index number, used in Participation list (shown in the GUI).

Format: deleteParticipation INDEX

Examples:

  • deleteParticipation 2

Handling Competition During a Competition event

This feature handles the entire flow of each session during Meet Day. It allows event organisers to submit a person(athlete)’s Squat, Bench, Deadlift attempts, as well as the success of their lifts. It will show the relevant information to prepare for the athletes lift (displaying name, weight, etc). The flow of events, and the commands to facilitate the competition session will be presented in order below:

This feature handles the entire flow of each session during Meet Day. It allows event organisers to submit a person’s Squat, Bench, Deadlift attempts, as well as the success of their lifts. It will show the relevant information to prepare for the athletes lift (displaying name, weight, etc). The flow of events, and the commands to facilitate the competition session will be presented in order below:

Get the next lifter in line: next

Retrieves the next lifter according to weight lifted for that attempt, the weights he/she is going for that particular lift and attempt. If there are no more attempts to be made by any lifter, this command will trigger the end of the competition.

Format/Example: next

Updating success or failure of a lift: lift

Updates whether the person (athlete) succeeds in his/her attempt, or fails it. The lift updated will be the one that was just called up.

Format: lift Y/N

Examples:

  • lift N

  • lift Y

Contributions to the Developer Guide

Given below are sections (some but not all) I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

Context-Switching feature between sessions

Our features are mainly split into 2 contexts. An in-competition, and an out-of-competition session mode. A session is started when the user wants to start an existing competition to call lifters to perform their attempt, record them, and finally to view the ranking leader board for the competition, all within in-session mode. On the other hand, an out-session mode, when the user exits the competition session mode, is where all create, read, update delete of the Person, Competition, and Participation is done.

The reason for this context-switching feature is to prevent users from using out-session commands that are strictly for in-session mode and vice versa.

ActivityDiagram
Figure 1. Activity Diagram for average user flow from out to in-session.

The activity diagram above shows the average user flow of how the user can go in-session, and also distinctly shows the commands that can be done in each state. However, the end of every competition session does not signify the end of a user’s activity. The user can still go in and out of the competition session (start and end), to perform the different commands from the different states.

How it is being implemented

This is done using an instance of the Session class, which is exposed from the model manager. The session has a competition field to indicate the current competition that is ongoing during the session. If there is no competition set in the session, then there is no ongoing session. Using this simple but highly effective method, we are able to use very simple logic to achieve the necessary context-switching behaviour described in the above diagram.

In-Session

In-Session is the state where the user enters competition mode, where users can command the app to generate the next lifter, as well as record any attempt. At the end of the competition, the rank of the participants and competition can be viewed too, as long as a competition session has yet to end.

To handle the state of the competition, we have created a new Session class that is packaged into model and managed by the ModelManager. The Session class is a singleton class, and only has one instance in the ModelManager. The reason behind the use of a singleton class to handle sessions, is that we only want one ongoing session at any point in time. The singleton class will also only temporarily store its participation list, and participationAttempt list in relation to the ongoing session. Once the session ends, all data is reset. Any update in any objects such as the attempts or participation details will be handled by the ModelManager, which will be explained in more details in the respective features below.

SessionClassDiagram
Figure 2. Class Diagram of the Session package in the Model

Next feature

One of the main purpose of the in-session function is to generate the next lifter and his attempt details accordingly. In the Session class, the list of ParticipationAttempt is maintained so that athletes can make their attempt in order of the type of lift, attempt number, and in increasing weight to be attempted. Upon calling the next command, the next lifter is called up, and the following lifter should be asked to prepare for his lift, after the next lifter.

Format: next

Given below is the example flow of what the model does when the NextLifterCommand is executed after being parsed through the LogicManager.

Step 1: A new NextLifterCommand is constructed when the user inputs next in the command box. When NextLifterCommand#execute() is called, the model will get the following lifter, and store the ParticipationAttempt retrieved from Session#getFollowingLifter() in a local variable, to be returned together with the CommandResult later on.

Step 2: The ModelManager will call Session#NextLifter() to generate the next lifter and attempt in the form of a ParticipationAttempt object. If the Session is not prepared, which means that the imported ParticipationAttempts are not sorted, prepare() will be called internally. When this method is called, the ParticipationAttempt list in the Session will be sorted according to the new ParticipationAttemptComparator. When this is done, the session is now prepared, and next or following lifters can be generated based on this sorted list. (This method is usually called once just after starting the session.)

Step 3: The Session#NextLifter() method will then return the first ParticipationAttempt in the list. This is equivalent to the next lifter to make his attempt, since he is the top most in the sorted list.

Step 4: A new CommandResult will be returned. Details of the next and following ParticipationAttempt will be included and displayed in the Dialogue Box to the user.

NextSequenceDiagram
Figure 3. Sequence Diagram for the NextLifterCommand

End session feature

This feature ends the session, and shifts the user back to the out-session state. All data stored in the session will be reset to default.

Format: endSession

When we first implemented the session feature, the session can only be ended when a competition has ended, which means there are no more attempts to be made. However, we have now made it such that the user can switch between sessions as and when, even in the middle of the competition. This gives users more flexibility to switch between session states, without worrying about the state of the competition.

Out-Session

Start Session feature

The start session feature is a command to start a new competition session, when a user is not in competition state. As mentioned in Section 4.2. above, Session allows the user to start any competition session as and when, even when a competition has not ended (there are still attempts left to be made). To start a session, the user can enter the command with the specified competition.

Format: startSession c/COMPETITION_NAME

Given below is the flow of execution in the model after a StartSessionCommand#execute() is called.

Step 1: Model#startSession(comp, partList) is called, where comp is the Competition object to start the session with, and partList is the list of Participation who will be participating in this competition session. The method then calls Session#start(comp, partList).

Step 2: An internal call in the start() method, loadAttempts(p, p.getAttempts()), is made for every Participation object, p, by looping through the partList, loading all unattempted attempts into the participationAttemptList temporarily stored in the Session instance. (p.getAttempts() retrieves the list of all 9 Attempt instance that the participation has submitted at the start.)

Step 3: The loadAttempts() method will loop through all the 9 Attempt objects taken in as parameter, and checks if each has been attempted. If an Attempt by that Participation has not been attempted, a new ParticipationAttempt object will be created and added to the list.

Because of the way Session handles the initialising of every new session, be it starting a new competition, resuming a competition, or even starting a session with a competition that has already ended (all attempts have been made by the athletes) is made possible.

StartSequenceDiagram
Figure 4. Sequence Diagram for the StartSessionCommand
Create a new Participation

To create a new Participation, the associated Person and Competition must exist. If either doesnt, an exception will be thrown to the user through the result box to prompt the user to input an existing one.

Format: addParticipation n/PERSON_NAME c/COMPETITION_NAME s/S1/S2/S3 b/B1/B2/B3 d/D1/D2/D3

Note: S1 means the 1st attempted weight for the Squat and so on.

List Participation

The list participation feature allows the user to filter the participation list on the PCC app based on a particular competition. If no parameters (competition name) are taken in, the command will list out all of the participations stored in the system.

Format: listParticipation or listParticipation c/COMPETITION_NAME

Delete Existing Participation

The user can delete an existing participation, maybe in the case he/she has withdrawn or is disqualified from that competition.

Format: deleteParticipation INDEX

We have decided to use the index of the participation in the list to delete a participation instead of other parameter types, like the name or competition of the participation. The main reason is because, there may exist more than one participation with the same name and different competition, or different name and same competition.

Pros:

  • Takes in less parameters, user can type less.

  • Avoid complications between unmatched name and competition.

  • Easy to implement.

Cons:

  • User will have to scroll through the participation list on the app to type in the index.