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 asPartipation
orAttempt
; 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 participation (linking persons and competitions together)
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:
-
Squat
-
Bench
-
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.
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.
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.
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.
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.