Metadata-Version: 2.4
Name: shedding
Version: 0.1.0
Summary: Learn Python by building small projects in a terminal UI, without an AI writing your code.
Author: dio
License-Expression: MIT
Project-URL: Homepage, https://github.com/t3t5u0403/shedding
Project-URL: Source, https://github.com/t3t5u0403/shedding
Keywords: python,learning,tui,textual,exercises,pytest
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Education
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Education
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: textual[syntax]>=8.0
Requires-Dist: pytest>=8.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Dynamic: license-file

# shedding

A terminal app for getting solid at Python by building small projects, one lesson at a time,
without an AI writing your code.

```
┌ Lesson 11/29 ─────────────┐┌ solution.py ──────────────────────┐
│ # 11 · Grade book         ││ def average(scores):              │
│                           ││     ...                           │
│ ## Goal                   ││                                   │
│ ...                       ││                                   │
│ ## Hints                  ││                                   │
│ Hint 1 of 3 ...           ││                                   │
└───────────────────────────┘└───────────────────────────────────┘
┌ Results ── Tests │ Review ────────────────────────────────────┐
│ ✗ 2 failed, 9 passed                                          │
│  ✓ average of three scores                                    │
│  ✗ empty list averages to zero                                │
│      assert 0 == 0.0 ...                                      │
└───────────────────────────────────────────────────────────────┘
 F5 Run tests  F1 Hint  F2 Review  F3 Prev  F4 Next  F9 Settings  ^q Quit
```

## Install and run

```
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/shedding              # or: .venv/bin/python -m shedding
```

Options: `--lesson N` opens a specific lesson, `--lessons PATH` uses another lessons folder,
`--db PATH` uses another progress database. Progress, drafts and settings live in
`~/.local/share/shedding/shedding.db`.

## Keys

| Key | Action |
|---|---|
| F5 | Run the hidden tests against the code in the editor |
| F1 | Reveal the next hint (they appear under the lesson text) |
| F2 | Request a code review (only after the tests pass, only if enabled) |
| F3 / F4 | Previous / next lesson (your draft is saved automatically) |
| F9 | Settings: review on/off, Ollama URL and model |
| Esc | Switch focus between the lesson pane and the editor |
| Ctrl+S | Save the draft now (it also autosaves a second after you stop typing) |
| Ctrl+P | Command palette: jump to any lesson, reset a lesson to its starter code |
| Ctrl+Q | Quit |

## How lessons work

Each folder under `shedding/lessons/` is one project: a README with the goal, concepts and exact
requirements, a `starter.py` that is loaded into the editor, hints revealed one at a time,
and pytest tests the app runs but never shows. Your code is written to a temporary folder as
`solution.py` and pytest runs there in a subprocess with a timeout, no stdin and resource
limits, so an infinite loop or a stray `input()` just shows up as a failure.

The 29 lessons ramp in two ways. The topics go from variables to a SQLite-backed CLI, and
the scaffolding shrinks as you go:

- Lessons 01 to 04 are the basics, written as plain scripts: the starter holds given values,
  you compute the results, and the tests re-run your code with other values.
- Lessons 05 to 10 give you function stubs to fill in.
- Lessons 11 to 19 give you only a docstring; the README lists the required names and you
  write the signatures and pick your own helpers.
- Lessons 20 to 29 specify just the public surface. How you structure the program is yours
  to decide, and the tests only look at behaviour.

Reference solutions live in `solutions/`, which the app never reads. Don't look in there
while doing a lesson.

## Code review (optional)

Off by default. Enable it in Settings (F9) and point it at a running [Ollama](https://ollama.com)
server with a model pulled (the default is `qwen2.5-coder:7b`). After your tests pass, F2 asks
the model for feedback. It returns a structured list of issues with line numbers and concepts
to look up; anything that looks like code is stripped before it reaches the screen. It will
not write a fix for you.

## The snake, and skins

A pixel snake lives next to the results pane. It comments on what just happened (first pass,
fewer failures than last run, the same failures again, a timeout), hands out a general Python
tip when clicked or every few minutes, and after three runs without progress reveals the next
hint on its own. Hide it with "Toggle mascot" in the command palette or in Settings.

Skins change the colour theme, the labels, and who the snake is:

| Skin | Snake | Flavour |
|---|---|---|
| Classic | Monty | Friendly python, plain labels |
| Metal Gear | Snake | Bandana, cigarette, codec calls from Otacon and the Colonel, missions instead of lessons |

The Metal Gear skin also retells every lesson: same concepts and the same tests one to one,
but rations instead of pizzas, codec contacts instead of a contact book, and Mother Base GMP
instead of a finance tracker. Switching skins swaps the lesson text, starter and tests, keeps
your progress, and keeps a separate draft per skin.

Pick one in Settings (F9) or with "Skin: …" in the command palette. Adding a skin is one
entry in `shedding/skins.py`: a Textual theme, a labels table, pixel frames and a set of lines
per event.

## Verifying lessons

```
.venv/bin/python scripts/verify_lessons.py        # all lessons
.venv/bin/python scripts/verify_lessons.py 07 -v  # one lesson, every check
.venv/bin/python -m pytest tests                  # the app's own tests
```

For every lesson the verifier checks that the files and metadata are valid, the reference
solution passes all tests, the starter fails, and both deliberately wrong solutions import
cleanly but fail at least one test. Anything else is reported as broken and CI fails.
See `docs/authoring.md` for how to add a lesson.
