Training table generator Česky

Your running season on one sheet of paper.

Write down your races and how much you run now. The generator lays out the weeks up to race day as a printable table: one row per week, a cell for every day. Put it on the wall and colour a cell after each run.

You need your race dates, one recent race time and how far you run now, and about ten minutes at a terminal. Make your own

An example season, a month in: two tune-up races and an autumn marathon. Press a day to colour it, or press the boxes to log the week’s kilometres.

How the sheet works

Each row is a week, Monday to Sunday. The columns on the right say what the week holds: ER, the easy runs (12+12 is two easy runs of 12 km), QR, one quality run, and LR, the long run. The grey number at the end is the week’s planned distance. You decide on which day each run happens.

The quality run is written as a short code:

H: 6×1′
Hill repeats: six one-minute hard efforts uphill, by effort, not pace; jog back down.
I: 5×3′
Intervals: five three-minute repeats at interval pace.
T: 3×8′
Threshold: repeats at threshold pace, comfortably hard.
MP: 3×3 km
Repeats at marathon pace.
S
Strides: a shorter easy run with six relaxed 20-second accelerations, never a sprint.
RACE 21 km
A race in place of the session.
–
No session this week.

Intervals, threshold and marathon-pace repeats have two minutes of jogging between them.

The paces

The paces are printed under the table, worked out from one race you ran recently with Jack Daniels’ formula. A 3:30:02 marathon, for example, gives easy runs at 5:37 per km, threshold at 4:40, intervals at 4:18 and marathon pace at 4:59. You can also set any of them yourself.

Colouring it in

When you’ve done a run, colour its day. The sheet itself is black and white and the colours are yours; these are the ones the author uses:

  • easy run
  • quality run
  • long run
  • something unexpected: illness, a trip

At the end of the week, colour one box for every kilometre you ran. A week counts as fully done at 80 % of its planned kilometres, so a missed run doesn’t spoil it. The colour says how the week went:

  • 80 % or more: done
  • 50 to 80 %
  • under 50 %

The idea behind it

An outline, not a prescription. No season goes to plan. You get ill, work runs late, you travel. The sheet shows the shape of the season, and you adapt the details as you go. Two rules printed on every sheet say what to give up first:

Short on time: drop an easy run, then intensity, then the long run.

Tired or ill: drop intensity first.

Grown from practice, checked against coaching guidance. Three weeks of building, then a lighter week. Quality sessions that grow a little each time they come round. Before each important race, a block aimed at that race, then a taper; after it, recovery and an easier week back into training. These rules started as the author’s own plan for his 2026 season, and each one was then checked against published coaching guidance and changed where the two disagreed. His threshold pace, for example, was about 10 seconds per km too fast for his race result; the generator now works it out with Jack Daniels’ formula. Every rule and its source is listed in the training model.

Make your own

The generator runs on your own computer, from the terminal. You don’t need to know how to program, but you will type a few commands. It takes about ten minutes the first time.

  1. Install it once

    You need Python 3.11 or newer and Git. Then, in a terminal:

    git clone https://github.com/f-hluchnik/training-table-generator.git
    cd training-table-generator
    python3 -m venv .venv
    . .venv/bin/activate
    pip install -e .

    On Windows, the fourth line is .venv\Scripts\activate, and py -3 replaces python3. Run the fourth line again in every new terminal before using the generator.

  2. Describe your season

    Create a text file, for example my-season.toml, with your races, a recent race result and how far you run now:

    start = 2027-05-03              # the first week of the plan
    
    [[race]]
    name = "Běhej lesy Lednice"
    date = 2027-10-09
    distance_km = 42.195
    
    [paces]
    # a race you ran recently; all paces are worked out from it
    race_result = { distance_km = 42.195, time = "3:30:02" }
    
    [load]
    easy_run_km = 12                # the length of one easy run
    long_run_km = 15                # your long run now

    That is all the generator needs. Dates are written without quotes.

  3. Build the sheet

    ttg build my-season.toml

    The PDF appears in a folder out next to your file. The generator never refuses a plan: if two races are close together or the season starts late, it still builds the sheet, shortens what has to give, and prints a warning in the terminal. If the file has a mistake, the message names the field at fault and nothing is written.

  4. Print it

    On A4, landscape, at 100 % (not “fit to page”), so the cells are big enough to colour. To change the plan later, edit your file and build again.

Common changes

Add any of these to your file:

  • More races. Add a [[race]] section for each. Mark a tune-up race inside your training with priority = "C", an important race that isn’t your main goal with priority = "B".
  • A trail or mountain race. Add hilly = true to its section.
  • A goal marathon pace. Add mp = "4:55" under [paces].
  • More runs a week. Add runs_per_week = 5 under [load]; the default is 4.
  • One week different. Add [overrides] with, for example, 14 = { long_run_km = 30 }.

Every field and its default is in the reference below.

Keep your paces current

Your paces come from one race result, so they don’t follow your fitness on their own. Check them after each important race and every two or three months: let your easy runs get faster at the same heart rate, but change threshold and marathon pace only after a race or a test run. Then build the sheet again.

Reference

Everything else the generator can do, for when you need it.

Every field of the season file

Only the fields marked required must be in the file. A misspelled field is reported as an error, so a typo is never silently ignored.

The plan

start date
Week 1 is the Monday-to-Sunday week that contains this date.
weeks number
Instead of start: the plan’s length in weeks, ending with the week of the last race. Give one of the two, not both. With neither, the plan starts next Monday.

Races: [[race]]

One section per race, as many as you like, on any dates.

name text, required
Printed under the table. Each race needs its own name.
date date, required
The race day, or the first day of a race over several days.
end date
The last day of a race over several days.
distance_km number, required
Decides how the race is trained for: up to 10 km, half marathon, marathon, or longer (ultra).
priority "A", "B" or "C", default "A"
A is a main goal, with a full taper and recovery. B is important, with a taper one week shorter. C is a tune-up race inside your training, with no taper or recovery of its own: a C race up to 10 km takes the place of the quality run, a longer one the place of the long run.
taper_weeks, specific_weeks, recovery_weeks numbers
Change the length of the race’s taper (including race week), its race-specific block and its recovery; see how long each phase is. Not for C races.
hilly true or false, default false
For a course where climbs, not a steady pace, decide the effort, such as a trail or mountain race. In the weeks aimed at it, every other quality run is hill repeats, threshold work replaces marathon pace, and the long runs have no marathon-pace kilometres. Not for C races.

Paces: [paces]

race_result required
A race you ran recently, as { distance_km = 21.1, time = "1:39:30" }. The time is "h:mm:ss" or "m:ss". Every pace is worked out from it.
easy, mp, threshold, interval "m:ss" per km
Set a pace yourself instead of the worked-out one: easy runs, marathon pace, threshold, intervals. mp is the place for a goal marathon pace. A threshold pace far from the worked-out one gets a warning.

Your running now: [load]

easy_run_km number, required
The length of one easy run. It stays the same all season; in lighter weeks the last one is halved.
long_run_km number, required
The long run of the first week. It grows by 2 km in each building week, up to a limit set by the race.
runs_per_week 3 to 6, default 4
Always one quality run and one long run; the others are easy runs.

The sheet: [sheet]

title text, default "training plan"
The title at the top of the sheet.
rules list of texts
The rules printed under the table, such as rules = ["Short on time: drop an easy run."]. Without it, the sheet prints its own.

Changing single weeks: [overrides]

Change any week by its number. The change applies to that week only; the weeks after it are still planned as before.

[overrides]
1  = { easy = "reduced" }                                  # "regular" or "reduced": the last easy run halved
13 = { quality = { type = "H", reps = 10, minutes = 1 } }  # any quality session
14 = { long_run_km = 30 }                                  # 0 = no long run
20 = { note = "holiday" }                                  # replaces the grey number at the end

A quality session is { type, reps, minutes } or { type, reps, km }, with type one of "H", "I", "T", "MP". Strides are { type = "S" }, no quality run is { type = "none" }. A race can’t be replaced.

How long each phase is

The plan is laid out backwards from each A and B race. The lengths are in weeks; the long run never goes above its limit.

Race Taper, with race week Race-specific block Recovery Longest long run
up to 10 km13116 km
half marathon24221 km
marathon26232 km
ultra36340 km

When there isn’t room for all of it, the build weeks give way first, then the race-specific block, then the recovery after the previous race, then the taper. Each shortened block gets a warning.

What the warnings mean

Warnings never stop the build. Each starts with a code:

C1
Races are close together: a block was shortened because of the previous race.
C2
The plan starts too late for the first main race.
C3
The easy runs and the long run grow by more than 10 % from one week to the next.
C4
The long run is more than half of the week.
C5
The long run is above the race’s limit.
C6
More than 40 minutes at threshold pace in one session.
C7
More than 10 km, or 8 % of the week, at interval pace in one session.
C8
A threshold pace you set is more than 10 seconds per km away from the worked-out one.
C9
Hill repeats longer than 2 minutes, or more than 20 minutes of hill effort in one session.