Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions PLANNING.md

This file was deleted.

168 changes: 49 additions & 119 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,155 +1,95 @@
<!-- Logo -->
<h1 align="center">
<img src="https://github.com/willtheorangeguy/PyWorkout/blob/main/docs/images/logo.png" height="250px" width="400px" alt="PyWorkout">
<img src="https://raw.githubusercontent.com/willtheorangeguy/.github/main/icons/PyWorkout/logo.png" height="250px" width="400px" alt="PyWorkout">
<br>
PyWorkout
<br>
</h1>

<!-- Copy -->
<h4 align="center">A minimal CLI to keep you inspired during your workout!</h4>
<h4 align="center">A minimal CLI to keep you inspired during your workout.</h4>

<!-- Badges -->
<div align="center">
<!-- Stability -->
<img alt="Docker Build State" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/docker-publish.yml/badge.svg">
<!-- Stability -->
<img alt="PyPI Build State" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/push-to-pypi.yml/badge.svg">
<!-- Stability -->
<img alt="Pylint State" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/pylint.yml/badge.svg">
<!-- CodeQL -->
<img alt="CodeQL State" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/codeql-analysis.yml/badge.svg">
<!-- Version -->
<img alt="GitHub Version" src="https://img.shields.io/github/v/release/willtheorangeguy/PyWorkout?include_prereleases">
<!-- Issues -->
<img alt="GitHub Issues" src="https://img.shields.io/github/issues/willtheorangeguy/PyWorkout">
<!-- Pull Requests -->
<img alt="GitHub Pull Requests" src="https://img.shields.io/github/issues-pr/willtheorangeguy/PyWorkout">
<!-- Discord -->
<img alt="Discord Server ID" src="https://img.shields.io/discord/947657440579711016">
<!-- Downloads -->
<img alt="Downloads" src="https://img.shields.io/github/downloads/willtheorangeguy/PyWorkout/total">
<!-- Language Count -->
<img alt="GitHub Languages" src="https://img.shields.io/github/languages/count/willtheorangeguy/PyWorkout">
<img alt="Tests" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/tests.yml/badge.svg">
<img alt="Pylint" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/pylint.yml/badge.svg">
<img alt="Docker Build" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/docker-publish.yml/badge.svg">
<img alt="PyPI Build" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/push-to-pypi.yml/badge.svg">
<img alt="CodeQL" src="https://github.com/willtheorangeguy/PyWorkout/actions/workflows/codeql-analysis.yml/badge.svg">
<img alt="Version" src="https://img.shields.io/github/v/release/willtheorangeguy/PyWorkout?include_prereleases">
<img alt="Issues" src="https://img.shields.io/github/issues/willtheorangeguy/PyWorkout">
<img alt="Pull Requests" src="https://img.shields.io/github/issues-pr/willtheorangeguy/PyWorkout">
<img alt="License" src="https://img.shields.io/github/license/willtheorangeguy/PyWorkout">
</div>

<!-- Navigation -->
<p align="center">
<a href="#key-features">Key Features</a> •
<a href="#download">Download</a> •
<a href="#how-to-use">How To Use</a> •
<a href="#installation">Installation</a> •
<a href="#usage">Usage</a> •
<a href="#documentation">Documentation</a> •
<a href="#support">Support</a> •
<a href="#contributing">Contributing</a> •
<a href="#changelog">Changelog</a> •
<a href="#credits">Credits & Contributors</a>
<a href="#license">License</a>
</p>

<!-- Screenshot(s) -->
![screenshot](https://github.com/willtheorangeguy/PyWorkout/blob/main/docs/images/welcome.png)
<!-- Hero -->

## Key Features

* Easy to run and understand with simple commands.
* Large list of muscle groups and workout activities.
* Automatic workout selection by day.
* Time and percentage complete indicators.
* Step by step guide through a workout program.
* Statistics view.
* Can skip unlikeable workouts.
* Able to customize number of workouts, muscle groups, type of workout and more.
* Cross platform.

## Download

You can **[download](https://github.com/willtheorangeguy/PyWorkout/releases/latest) the source code** to run the scripts from the command line on Windows, macOS and Linux. **This will require [Python](https://www.python.org/downloads/).**
![PyWorkout running in a terminal](https://raw.githubusercontent.com/willtheorangeguy/.github/main/icons/PyWorkout/welcome.png)

You can **[download](https://github.com/willtheorangeguy/PyWorkout/releases/latest) the latest executable version** of PyWorkout for Windows. **This does not require Python.**

## How To Use

To run the application, you can use [Git and the Python Interpreter](https://github.com/willtheorangeguy/PyWorkout/main/README.md#git), which allows you to clone and run the application, [`pip`](https://github.com/willtheorangeguy/PyWorkout/main/README.md#pip) to create a command line application, or [Docker](https://github.com/willtheorangeguy/PyWorkout/main/README.md#docker) to create a container of the application.
## Key Features

### Git
* Pick a muscle group and get walked through the workout one exercise at a time.
* Nine muscle groups covering the whole body, each with its own set and rep counts.
* Live elapsed time and percent complete after every exercise.
* Skip anything you would rather not do, and see full statistics at the end.
* Open a local video for the current muscle group with one command.
* Add exercises, change rep counts, and swap videos by editing plain Python lists.
* No runtime dependencies beyond the standard library. Runs on Windows, macOS, and Linux.

To clone and run this application, you'll need [Git](https://git-scm.com/downloads) and [Python](https://www.python.org/downloads/) installed on your computer. If you would rather not use Git, you can just download the script from GitHub above. From your command line:
## Installation

```bash
# Clone this repository
$ git clone https://github.com/willtheorangeguy/PyWorkout

# Go into the repository
$ cd PyWorkout

# Run the CLI
$ python main.py
pip install pyworkout
```

### `pip`
Prefer a standalone Windows executable, the source, or a container? See [Installation](docs/installation.md).

You can install the program from the [Python Package Index](https://pypi.org/project/PyWorkout/) through `pip`.
## Usage

```bash
# Install via pip
$ pip install pyworkout
Start the CLI, choose a muscle group, then step through the workout:

# Run the CLI
```console
$ pyworkout
```
Which muscle group would you like to work out? abs

### Docker
> start
You have started the abs muscle group.
The current time is: 14:19:35
You have completed: 0%
Please complete 2 Sets of 25 Reps of Situps

You can pull the [Docker](https://www.docker.com/) image from GitHub Packages. From your command line:
> next
You have completed: 16%
Please complete 2 Sets of 25 Reps of Reverse Crunches

```bash
# Pull image
$ docker pull ghcr.io/willtheorangeguy/pyworkout:main

# Run container
$ docker run -i -t ghcr.io/willtheorangeguy/pyworkout:main python main.py
> end
```

## Support
`help` lists every command. The full reference is in [Commands](docs/commands.md).

**The following commands are available (can be generated by using the `help` command):**

```text
list Lists the workout activities by muscle group.
start Starts the workout and displays the first workout activity.
next Moves to the next workout activity.
skip Skips the current workout activity.
end Completes the workout and display full workout statistics.
stats Shows workout statistics at any point (does not work with the `skip` command).
video Opens the workout video assigned to each muscle group.
license Shows the license.
help Prints this help text.
quit Ends the program.
```

Note: the `skip` command cannot be used in conjunction with the `stats` command.
## Documentation

**To use the `video` command, you must change the video variables.** To do so:
Full documentation lives in [`docs/`](docs/README.md):
[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)

1. Open `main.py` in a text editor.
2. Change the _Video File Paths_ variables to the **absolute** path for each video by muscle group (double slashes (`\\`) are only necessary on Windows).

```python
# Video File Paths
abs_video = "D:\\Videos\\Workout Videos\\10 Minute Ab Workout.mp4" # change these to personal video path
```

3. Running the `video` command will now include your local workout videos.
## Support

Customizing the list of workouts, workout activities and number of activities can be found in [`CUSTOMIZATION.md`](https://github.com/willtheorangeguy/PyWorkout/tree/main/docs). More documentation is available in the **[Documentation](https://github.com/willtheorangeguy/PyWorkout/tree/main/docs)** and on the **[Wiki](https://github.com/willtheorangeguy/PyWorkout/wiki)**. If more support is required, please open a **[GitHub Discussion](https://github.com/willtheorangeguy/PyWorkout/discussions/new)** or join our **[Discord](https://discord.gg/YFMcACG9rh)**.
Open a [GitHub Discussion](https://github.com/willtheorangeguy/PyWorkout/discussions/new) or file an [issue](https://github.com/willtheorangeguy/PyWorkout/issues/new/choose).

## Contributing

Please contribute using [GitHub Flow](https://guides.github.com/introduction/flow). Create a branch, add commits, and [open a pull request](https://github.com/willtheorangeguy/PyWorkout/compare).

Please read [`CONTRIBUTING`](https://github.com/willtheorangeguy/.github/blob/main/CONTRIBUTING.md) for details on our [`CODE OF CONDUCT`](https://github.com/willtheorangeguy/.github/blob/main/CODE_OF_CONDUCT.md), and the process for submitting pull requests to us.

## Changelog

See the [`CHANGELOG`](CHANGELOG.md) file for details.
Contributions welcome. See the org-wide [Contributing Guide](https://github.com/willtheorangeguy/.github/blob/main/CONTRIBUTING.md) and [Code of Conduct](https://github.com/willtheorangeguy/.github/blob/main/CODE_OF_CONDUCT.md).

## Credits

Expand Down Expand Up @@ -177,16 +117,6 @@ This software uses the following open source packages, projects, services or web
</tr>
</table>

## Contributors

* [@willtheorangeguy](https://github.com/willtheorangeguy) - Sponsor on [PayPal](https://paypal.me/wvdg44?country.x=CA&locale.x=en_US)

## You may also like...

* [ProgramVer](https://github.com/willtheorangeguy/ProgramVer) - An open-source, Python GUI version window to show copyright info and licenses.
* [Periodic Table Info](https://github.com/willtheorangeguy/Periodic-Table-Info) - Print all the elements in the Periodic Table of the Elements, with an interactive prompt to learn more.
* [PyAvatar](https://github.com/willtheorangeguy/PyAvatar) - Easily display all of your creative avatars to keep them consistent across websites.

## License

This project is licensed under the [MIT License](https://mit-license.org/) - see the [`LICENSE`](LICENSE.md) file for details.
MIT see [`LICENSE.md`](LICENSE.md).
49 changes: 37 additions & 12 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,38 @@
# PyWorkout Documentation

This folder includes all of the docs for PyWorkout. More can be found on the [wiki](https://github.com/willtheorangeguy/PyWorkout/wiki).

```text
├── docs
| ├── images
| ├── USAGE.md
| ├── COMMANDS.md
| ├── CUSTOMIZATION.md
| ├── TESTING.md
└── README.md
# PyWorkout — Documentation

A terminal workout tracker: pick a muscle group, work through its exercises, and get timing
and completion statistics as you go. Ships to PyPI, GHCR, and as a Windows executable.

```
PyWorkout/
├── docs/
│ ├── README.md this page
│ ├── quickstart.md install, pick a group, finish a session
│ ├── installation.md all four install paths
│ ├── usage.md the session flow
│ ├── commands.md every command with example output
│ ├── configuration.md exercises, videos, and what needs source edits
│ ├── architecture.md how main.py and gui.py are shaped
│ ├── development.md contributing to the code
│ ├── testing.md the test suite and coverage
│ ├── faq.md skip/stats, the GPL banner, what gui.py is
│ ├── troubleshooting.md concrete failures and fixes
│ └── roadmap.md planned work and known defects
├── main.py the CLI
├── gui.py a separate Tkinter percentage tracker
└── tests/
```

## Pages

- [Quickstart](./quickstart.md) — install, run one workout
- [Installation](./installation.md) — PyPI, source, Docker, Windows executable
- [Usage](./usage.md) — how a session flows
- [Commands](./commands.md) — full command reference with example output
- [Configuration](./configuration.md) — adding exercises and video paths
- [Architecture](./architecture.md) — the shape of the code and what follows from it
- [Development](./development.md) — working on it
- [Testing](./testing.md) — the suite, coverage, and writing new tests
- [FAQ](./faq.md) — why `stats` stopped, what `gui.py` is, the licence banner
- [Troubleshooting](./troubleshooting.md) — Tkinter, Docker, `PATH`, timing
- [Roadmap](./roadmap.md) — version 2.0.0 and known defects
33 changes: 0 additions & 33 deletions docs/USAGE.md

This file was deleted.

80 changes: 80 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# PyWorkout — Architecture

## Layout

```
PyWorkout/
├── main.py the CLI — command loop, workout data, all session state
├── gui.py a separate Tkinter percentage tracker
├── __main__.py module entry point (python -m pyworkout)
├── docker-compose.yml containerised run
├── Dockerfile published to GHCR
├── pyproject.toml packaging; published to PyPI
├── setup.cfg pytest and coverage configuration
└── tests/
├── test_main.py CLI behaviour
└── test_gui.py GUI components
```

## Two programs, not one

`main.py` and `gui.py` are independent. The CLI does not import the GUI, and the GUI is not
a front end for the CLI — it is a separate Tkinter window that displays percentage
completion for a fixed exercise list.

They share the project and the name, and nothing else. Worth knowing before looking for the
integration point: there isn't one.

## `main.py` is a single function

The entire CLI — muscle-group selection, the command loop, timing, statistics, help output,
and the exercise data itself — lives inside one `workout()` function of roughly six hundred
lines.

Consequences that show up in practice:

- **Session state is local variables**, which is why `skip` and `stats` interact badly:
they manipulate overlapping bookkeeping in the same scope rather than through a shared
model. See [Roadmap](./roadmap.md).
- **Help text is printed inline in two places** (around lines 613 and 632) and the two
copies have drifted — one documents the `skip`/`stats` limitation, the other omits it.
- **Tests reach the logic through `builtins.input` and `builtins.print`.** Every test in
`test_main.py` patches those and asserts against captured output, because there is no
return value to inspect. That is a consequence of the structure, not a testing choice.

Extracting the workout data and the session state into their own modules is the change that
would unlock most of the rest.

## Data

Exercise definitions — muscle groups, exercises, sets, reps — are literals in `main.py`.
There is no data file, no database, and nothing persisted between runs. Closing the program
discards the session.

Video paths are also literals, under a `# Video File Paths` comment, which is why the
`video` command requires editing source to work. See [Configuration](./configuration.md).

## Timing

Elapsed time is computed from a start timestamp captured by `start` and compared against
the current time on each `next`, `stats`, and `end`. There is no pause, and no persistence —
the timer measures wall-clock time from `start`, including any time you spent away from the
terminal.

The known timer defect tracked for 2.0.0 lives here.

## Distribution

The same code ships four ways: PyPI (`pip install pyworkout`), a GHCR container, a Windows
executable attached to releases, and the source itself. `pyproject.toml` drives the first,
`Dockerfile` the second.

Because the PyPI and GHCR pages render the README off-site, its images must be absolute
URLs — they point at `.github/icons/PyWorkout/`. Relative image paths would break there
even though they work on github.com.

## Testing

`setup.cfg` configures pytest with coverage, branch coverage, and three report formats.
Coverage sits around 54%. GUI tests skip in headless environments, since Tkinter needs a
display — expected in CI rather than a failure.
Loading