Trainerflow Docs trainerflow.com
Getting started › Your first program

Getting started

Your first program

Write a simple two-day strength program from scratch, run it in the simulator and see how the pieces fit together.

To start things simple, our first program will be a general strength and conditioning two-day split that consists mainly of compound exercises. The first day focuses on upper-body exercises and the second on lower-body exercises. This is what we are building:

Day 1

Exercise Sets × Reps Weight
Bench press 4 × 8 60 kg
Bicep curl 3 × 10 25 kg
Overhead press 4 × 8 35 kg

Day 2

Exercise Sets × Reps Weight
Back squat 4 × 8 70 kg
Deadlift 3 × 5 95 kg

Again, this is an extremely simple program with no interactivity and no configurability, i.e. the sets, reps and weights are fixed. Also note that we will define everything from scratch; apart from resting, we won’t use the standard library that Trainerflow provides.

The SPDK

Assuming that you have a Trainerflow account, go to Programs and press New program. If all goes well, the Sports Programming Development Kit (SPDK for short) opens up.

The SPDK consists mainly of a file explorer on the left, a code editor in the middle and a simulator on the right that you can use to run and test your program. In the explorer you can see a single file called main.cl. This file is the entry point of the program: it is what runs when the program runs.

There is no save button. The SPDK saves as you type and checks your program while it does, so mistakes show up underlined in the editor and listed under Problems in the explorer. You can read more in programs and the SPDK.

Process

Actions

The first thing the athlete does is a set of 8 reps of bench press at 60 kg. To say that in Coach we first need something to name the bench press itself. That is an action: something the athlete can perform.

action BenchPress [title: "Bench press"]

The part in square brackets holds the action’s properties. The title is what the athlete sees on their screen. We do the same for every exercise of the program:

action BenchPress [title: "Bench press"]
action BicepCurl [title: "Bicep curl"]
action OverheadPress [title: "Overhead press"]
action BackSquat [title: "Back squat"]
action Deadlift [title: "Deadlift"]

By convention, actions are named in PascalCase.

Outputs

Next we need to tell the athlete how many reps and how much weight. Each of those is an output: something that can be specified. An output, besides its name, needs a type. reps is a plain number, so its type is number. weight is a measurement in kilograms, so its type is the unit |kg|.

output:number reps [title: "Reps"]
output:|kg| weight [title: "Weight"]

Because these outputs are not tied to any particular exercise, we declare them once, near the top of the file, and use them everywhere.

Execs

Now that we have both the actions and the outputs, we can put together the first specification. Generally, every execution of an exercise, every set, is modelled as an exec. An exec looks a lot like a function in other languages, with a name, parameters and a body:

exec bench() {
    specify:BenchPress reps 8, weight 60|kg|
}

The body holds a single specify command. A specification needs three things: an action, an output and the output’s value. Here we say that the athlete should perform BenchPress for 8 reps at 60|kg|. You can read more about the values that Coach understands, and measurements like 60|kg| in particular.

Every time we call bench(), the athlete will be given this specification: 8 reps of bench press at 60 kg. The program then waits for them to finish the set before it goes on. We do the same for the rest of the exercises:

exec bicep_curl() {
    specify:BicepCurl reps 10, weight 25|kg|
}

exec ovh_press() {
    specify:OverheadPress reps 8, weight 35|kg|
}

exec squat() {
    specify:BackSquat reps 8, weight 70|kg|
}

exec deadlift() {
    specify:Deadlift reps 5, weight 95|kg|
}

Repeat

An exec definition is just that: a definition. It does nothing by itself unless we call it, once or many times. The bench press needs 4 sets, so we could write bench() four times in a row, or we can use the repeat command:

repeat 4 { bench() }

Groups

Our program consists of two different days, so the natural thing to do is to define two groups, day1 and day2. A group gathers commands under a name, and calling the group runs them all:

group day1() {
    repeat 4 { bench() }
    repeat 3 { bicep_curl() }
    repeat 4 { ovh_press() }
}

group day2() {
    repeat 4 { squat() }
    repeat 3 { deadlift() }
}

Rest

We have several options as to how often the athlete trains but, to keep things simple, we will have them train day1 and day2 alternately with one day off in between. Resting is so common that the standard library already has it, so we import it at the very top of the file:

import "coach/common/rest.cl"

and then call rest with the amount of time the athlete should rest:

day1()
rest(2|day|)
day2()
rest(2|day|)

Program span

You might think that we are finished, but if you look closely we have only described 4 days in total: day 1, a day off, day 2 and another day off. Let us say that the program should last roughly a month (really, it can be as long or as short as you like). Four days, seven times, is 28 days, so we wrap the schedule in one more repeat:

repeat 7 {
    day1()
    rest(2|day|)
    day2()
    rest(2|day|)
}

The whole program

Putting everything together, this is our main.cl:

import "coach/common/rest.cl"

action BenchPress [title: "Bench press"]
action BicepCurl [title: "Bicep curl"]
action OverheadPress [title: "Overhead press"]
action BackSquat [title: "Back squat"]
action Deadlift [title: "Deadlift"]

output:number reps [title: "Reps"]
output:|kg| weight [title: "Weight"]

exec bench() {
    specify:BenchPress reps 8, weight 60|kg|
}

exec bicep_curl() {
    specify:BicepCurl reps 10, weight 25|kg|
}

exec ovh_press() {
    specify:OverheadPress reps 8, weight 35|kg|
}

exec squat() {
    specify:BackSquat reps 8, weight 70|kg|
}

exec deadlift() {
    specify:Deadlift reps 5, weight 95|kg|
}

group day1() {
    repeat 4 { bench() }
    repeat 3 { bicep_curl() }
    repeat 4 { ovh_press() }
}

group day2() {
    repeat 4 { squat() }
    repeat 3 { deadlift() }
}

repeat 7 {
    day1()
    rest(2|day|)
    day2()
    rest(2|day|)
}

Simulation

Now let’s see how we can run our program and test whether it behaves as it should. On the right-hand side of the editor sits the simulator, a phone that shows exactly what the athlete will see. Press Run the program to start it.

If everything goes swimmingly 🤞 you should see the first specification: 8 reps of bench press at 60 kg. Pressing the big arrow continues the program to the next set, and Back steps back to the previous one. Press it a few times to see how the program progresses and whether you missed any steps.

There is no need to restart the simulator when you change the code. It replays what you have done so far against the new version of the program, so you can tweak and watch at the same time. You can read all about it in the simulator.

Final remarks

You may have noticed that doing something very simple, such as the program we just built, requires a fair amount of ceremony. Notice though that we defined everything from scratch, something that you won’t normally do, because the standard library already has most of the things you will need, defined and ready to use. With it, the bench press of day 1 is an import and a single line:

import "coach/strength/push.cl"

bench_press([weight: 60|kg|, reps: 8], [reps: true], [location: true])

which also asks the athlete how many reps they actually managed.

Next steps

There are a lot of things we didn’t cover here, because this was just a very gentle introduction to athletic programming with Trainerflow. For example, we didn’t see how to use the measure command to ask the athlete for feedback, how to store the result of an exec and use it later to take a decision, or how to use the standard library. It is a good idea to dig into the core elements and then read about the available commands. That will give you a good understanding of how Coach works. The examples then show complete, adaptive programs.