Skip to content

Commit 43b71aa

Browse files
docs: add quickstart, architecture, faq, troubleshooting, and roadmap pages
Brings docs/ up to the revised standard page set. PLANNING.md moves into docs/roadmap.md alongside the defects found while documenting. api.md omitted: there is no API surface. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TtaJBmFDK3GcSyuhSuZ84R
1 parent e00e112 commit 43b71aa

8 files changed

Lines changed: 365 additions & 27 deletions

File tree

PLANNING.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Please complete 2 Sets of 25 Reps of Reverse Crunches
8181
## Documentation
8282

8383
Full documentation lives in [`docs/`](docs/README.md):
84-
[Installation](docs/installation.md) · [Usage](docs/usage.md) · [Commands](docs/commands.md) · [Configuration](docs/configuration.md) · [Development](docs/development.md) · [Testing](docs/testing.md)
84+
[Quickstart](docs/quickstart.md) · [Installation](docs/installation.md) · [Usage](docs/usage.md) · [Commands](docs/commands.md) · [Configuration](docs/configuration.md) · [Architecture](docs/architecture.md) · [FAQ](docs/faq.md) · [Troubleshooting](docs/troubleshooting.md) · [Roadmap](docs/roadmap.md)
8585

8686
## Support
8787

docs/README.md

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
1-
# PyWorkout Documentation
1+
# PyWorkout Documentation
22

3-
Everything beyond the [README](../README.md) lives here.
3+
A terminal workout tracker: pick a muscle group, work through its exercises, and get timing
4+
and completion statistics as you go. Ships to PyPI, GHCR, and as a Windows executable.
45

5-
```text
6-
├── docs
7-
| ├── installation.md Every way to install and run PyWorkout
8-
| ├── usage.md Running a workout from start to finish
9-
| ├── commands.md Full command reference with example output
10-
| ├── configuration.md Adding exercises, changing reps, setting video paths
11-
| ├── development.md Local setup, linting, building, releasing
12-
| └── testing.md Test suite structure and how to run it
13-
└── README.md
6+
```
7+
PyWorkout/
8+
├── docs/
9+
│ ├── README.md this page
10+
│ ├── quickstart.md install, pick a group, finish a session
11+
│ ├── installation.md all four install paths
12+
│ ├── usage.md the session flow
13+
│ ├── commands.md every command with example output
14+
│ ├── configuration.md exercises, videos, and what needs source edits
15+
│ ├── architecture.md how main.py and gui.py are shaped
16+
│ ├── development.md contributing to the code
17+
│ ├── testing.md the test suite and coverage
18+
│ ├── faq.md skip/stats, the GPL banner, what gui.py is
19+
│ ├── troubleshooting.md concrete failures and fixes
20+
│ └── roadmap.md planned work and known defects
21+
├── main.py the CLI
22+
├── gui.py a separate Tkinter percentage tracker
23+
└── tests/
1424
```
1525

16-
## Where to Start
26+
## Pages
1727

18-
| If you want to… | Read |
19-
| --- | --- |
20-
| Get PyWorkout running | [Installation](installation.md) |
21-
| Do a workout | [Usage](usage.md) |
22-
| Look up what a command does | [Commands](commands.md) |
23-
| Add your own exercises or videos | [Configuration](configuration.md) |
24-
| Change the code | [Development](development.md) and [Testing](testing.md) |
28+
- [Quickstart](./quickstart.md) — install, run one workout
29+
- [Installation](./installation.md) — PyPI, source, Docker, Windows executable
30+
- [Usage](./usage.md) — how a session flows
31+
- [Commands](./commands.md) — full command reference with example output
32+
- [Configuration](./configuration.md) — adding exercises and video paths
33+
- [Architecture](./architecture.md) — the shape of the code and what follows from it
34+
- [Development](./development.md) — working on it
35+
- [Testing](./testing.md) — the suite, coverage, and writing new tests
36+
- [FAQ](./faq.md) — why `stats` stopped, what `gui.py` is, the licence banner
37+
- [Troubleshooting](./troubleshooting.md) — Tkinter, Docker, `PATH`, timing
38+
- [Roadmap](./roadmap.md) — version 2.0.0 and known defects

docs/architecture.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# PyWorkout — Architecture
2+
3+
## Layout
4+
5+
```
6+
PyWorkout/
7+
├── main.py the CLI — command loop, workout data, all session state
8+
├── gui.py a separate Tkinter percentage tracker
9+
├── __main__.py module entry point (python -m pyworkout)
10+
├── docker-compose.yml containerised run
11+
├── Dockerfile published to GHCR
12+
├── pyproject.toml packaging; published to PyPI
13+
├── setup.cfg pytest and coverage configuration
14+
└── tests/
15+
├── test_main.py CLI behaviour
16+
└── test_gui.py GUI components
17+
```
18+
19+
## Two programs, not one
20+
21+
`main.py` and `gui.py` are independent. The CLI does not import the GUI, and the GUI is not
22+
a front end for the CLI — it is a separate Tkinter window that displays percentage
23+
completion for a fixed exercise list.
24+
25+
They share the project and the name, and nothing else. Worth knowing before looking for the
26+
integration point: there isn't one.
27+
28+
## `main.py` is a single function
29+
30+
The entire CLI — muscle-group selection, the command loop, timing, statistics, help output,
31+
and the exercise data itself — lives inside one `workout()` function of roughly six hundred
32+
lines.
33+
34+
Consequences that show up in practice:
35+
36+
- **Session state is local variables**, which is why `skip` and `stats` interact badly:
37+
they manipulate overlapping bookkeeping in the same scope rather than through a shared
38+
model. See [Roadmap](./roadmap.md).
39+
- **Help text is printed inline in two places** (around lines 613 and 632) and the two
40+
copies have drifted — one documents the `skip`/`stats` limitation, the other omits it.
41+
- **Tests reach the logic through `builtins.input` and `builtins.print`.** Every test in
42+
`test_main.py` patches those and asserts against captured output, because there is no
43+
return value to inspect. That is a consequence of the structure, not a testing choice.
44+
45+
Extracting the workout data and the session state into their own modules is the change that
46+
would unlock most of the rest.
47+
48+
## Data
49+
50+
Exercise definitions — muscle groups, exercises, sets, reps — are literals in `main.py`.
51+
There is no data file, no database, and nothing persisted between runs. Closing the program
52+
discards the session.
53+
54+
Video paths are also literals, under a `# Video File Paths` comment, which is why the
55+
`video` command requires editing source to work. See [Configuration](./configuration.md).
56+
57+
## Timing
58+
59+
Elapsed time is computed from a start timestamp captured by `start` and compared against
60+
the current time on each `next`, `stats`, and `end`. There is no pause, and no persistence —
61+
the timer measures wall-clock time from `start`, including any time you spent away from the
62+
terminal.
63+
64+
The known timer defect tracked for 2.0.0 lives here.
65+
66+
## Distribution
67+
68+
The same code ships four ways: PyPI (`pip install pyworkout`), a GHCR container, a Windows
69+
executable attached to releases, and the source itself. `pyproject.toml` drives the first,
70+
`Dockerfile` the second.
71+
72+
Because the PyPI and GHCR pages render the README off-site, its images must be absolute
73+
URLs — they point at `.github/icons/PyWorkout/`. Relative image paths would break there
74+
even though they work on github.com.
75+
76+
## Testing
77+
78+
`setup.cfg` configures pytest with coverage, branch coverage, and three report formats.
79+
Coverage sits around 54%. GUI tests skip in headless environments, since Tkinter needs a
80+
display — expected in CI rather than a failure.

docs/faq.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# PyWorkout — FAQ
2+
3+
## Why can't I use `skip` and `stats` together?
4+
5+
Because they interfere. Once you skip an exercise, `stats` stops reporting for that session
6+
and prints "You cannot use both the `skip` and `stats` commands, sorry!"
7+
8+
This is a defect rather than a design decision — both commands manipulate the same session
9+
bookkeeping inside one large function. See [Architecture](./architecture.md) and
10+
[Roadmap](./roadmap.md).
11+
12+
## The `video` command does nothing.
13+
14+
It needs paths configured first. Video file paths are literals in `main.py`, under the
15+
`# Video File Paths` comment — the command opens whatever is listed there in your default
16+
player, and does nothing useful until you point it at real files. See
17+
[Configuration](./configuration.md).
18+
19+
## Does it save my workout history?
20+
21+
No. Nothing is persisted. Closing the program discards the session, and there is no history
22+
across runs.
23+
24+
## Can I add my own exercises?
25+
26+
Yes, by editing `main.py` — the muscle groups, exercises, sets, and reps are literals in
27+
the source. There is no data file. See [Configuration](./configuration.md).
28+
29+
## What's `gui.py`?
30+
31+
A separate Tkinter window that tracks percentage completion for a fixed exercise list. It
32+
is **not** a front end for the CLI — the two programs are independent and share nothing but
33+
the repository. Looking for how they connect is time wasted; they do not.
34+
35+
## Why does it print GPL text when the repo says MIT?
36+
37+
`main.py` prints GPL boilerplate at startup — "ABSOLUTELY NO WARRANTY", "free software",
38+
"redistribute it under certain conditions" — with a 2021-2024 copyright line. The
39+
repository is MIT-licensed, and `LICENSE.md` is the MIT text.
40+
41+
The startup banner is wrong. It is a leftover, tracked in [Roadmap](./roadmap.md), and the
42+
licence that governs the code is the one in `LICENSE.md`.
43+
44+
## Does the timer pause?
45+
46+
No. It measures wall-clock time from `start`, so time spent away from the terminal counts.
47+
A timer fix is the tracked item for version 2.0.0.
48+
49+
## Which install should I use?
50+
51+
`pip install pyworkout` unless you have a reason not to. Docker suits a throwaway
52+
environment; the Windows executable suits a machine with no Python. All four ship the same
53+
code — see [Installation](./installation.md).
54+
55+
## Why do GUI tests skip in CI?
56+
57+
Tkinter needs a display, and CI runners are headless. Expected behaviour, not a failure.
58+
59+
## Is this exercise advice?
60+
61+
No. It is a timer and a checklist. The exercises, sets, and reps are one person's routine
62+
hardcoded into a script, not a programme designed for anyone in particular.

docs/quickstart.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# PyWorkout — Quickstart
2+
3+
## Install
4+
5+
```bash
6+
pip install pyworkout
7+
```
8+
9+
Requires Python 3.9+. Other install paths — source, Docker, Windows executable — are in
10+
[Installation](./installation.md).
11+
12+
## Run
13+
14+
```bash
15+
pyworkout
16+
```
17+
18+
## Pick a muscle group
19+
20+
You are prompted for one. Both the number and the name work:
21+
22+
```
23+
1 abs 4 chest 7 back
24+
2 quads 5 arms
25+
3 glutes 6 shoulders
26+
```
27+
28+
## Work through it
29+
30+
```
31+
list show the exercises in this group
32+
start begin, and start the timer
33+
next move to the next exercise
34+
skip skip the current one
35+
stats progress so far
36+
end finish and show the summary
37+
quit exit
38+
```
39+
40+
A typical session is `start`, then `next` repeatedly, then `end`.
41+
42+
## What to expect
43+
44+
```
45+
You have started the abs muscle group.
46+
The current time is: 14:19:35
47+
You have completed: 0%
48+
Please complete 2 Sets of 25 Reps of Situps
49+
```
50+
51+
Each `next` reports elapsed time and percentage complete. `end` prints the total time and
52+
everything you finished.
53+
54+
## One thing that will catch you out
55+
56+
**`skip` and `stats` do not work together.** Once you have skipped an exercise, `stats`
57+
stops reporting for that session and says so. This is a known defect rather than a design
58+
choice — see [Roadmap](./roadmap.md).
59+
60+
## Then what
61+
62+
- [Usage](./usage.md) — the full session flow
63+
- [Commands](./commands.md) — every command with example output
64+
- [Configuration](./configuration.md) — adding your own exercises and videos

docs/roadmap.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# PyWorkout — Roadmap
2+
3+
## Version 2.0.0
4+
5+
- [ ] [#1](https://github.com/willtheorangeguy/PyWorkout/issues/1) — Fix Timer
6+
7+
More planning lives on the
8+
[Issues page](https://github.com/willtheorangeguy/PyWorkout/issues) and the
9+
[Projects page](https://github.com/willtheorangeguy/PyWorkout/projects?type=classic).
10+
11+
## Known defects
12+
13+
**`skip` and `stats` are mutually exclusive.** Using `skip` disables `stats` for the rest
14+
of the session, and the program says so rather than failing silently. Both commands
15+
manipulate overlapping session bookkeeping inside a single function — see
16+
[Architecture](./architecture.md). Extracting session state into its own model is what
17+
fixes this properly.
18+
19+
**The startup banner claims GPL terms on an MIT project.** `main.py` prints "ABSOLUTELY NO
20+
WARRANTY", "free software", and "redistribute it under certain conditions", with a
21+
2021-2024 copyright line. The repository is MIT and `LICENSE.md` is the MIT text. The
22+
banner is a leftover and contradicts the actual licence.
23+
24+
**Two help outputs have drifted.** Help text is printed inline in two places in `main.py`.
25+
One documents the `skip`/`stats` limitation; the other omits it, so which caveat you see
26+
depends on where you asked.
27+
28+
**`video` requires editing source to work at all.** Paths are literals under
29+
`# Video File Paths`. A command that does nothing until you modify the program is closer to
30+
unimplemented than configurable.
31+
32+
## Structural gaps
33+
34+
**`main.py` is one ~600-line function.** Muscle-group selection, the command loop, timing,
35+
statistics, help, and the exercise data all live inside `workout()`. This is the root cause
36+
of the `skip`/`stats` defect and the duplicated help text, and it is why tests have to reach
37+
the logic by patching `builtins.input` and `builtins.print` — there is no return value to
38+
assert against.
39+
40+
**Coverage is around 54%.** Reasonable for a prompt-loop program tested through stdout, but
41+
the untested half is where the timer and statistics logic lives.
42+
43+
**Exercises are hardcoded.** Adding your own means editing `main.py`. A data file would
44+
make the program useful to someone whose routine differs.
45+
46+
**Nothing persists.** No history, no progress across sessions, no record that a workout
47+
happened.
48+
49+
**The CLI and the GUI are unrelated programs.** `gui.py` tracks percentages for its own
50+
fixed exercise list and shares nothing with `main.py`.
51+
52+
## Non-goals
53+
54+
- **Exercise prescription.** This is a timer and a checklist over one person's routine, not
55+
a training programme.
56+
- **Accounts or sync.** It is a local script.

0 commit comments

Comments
 (0)