Skip to content
Merged
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
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ Quick cheatsheet for basic Python.

**This is a casual and unpolished personal project, started in Aug '26.**

I wrote and built this from scratch — it started as a few quick-reference explanations on loops and lists for high-school intro-Python students working on their first projects, and evolved from there. I couldn't find a resource my students would consistently use that had:
I wrote and built this from scratch, not as a complete Python language reference, but as a visualization of my mental model of how Python works.

It started as a few quick-reference explanations on loops and lists for high-school intro-Python students working on their first independent projects, and evolved from there. I couldn't find a resource my students would consistently use that had:

- simple explanations for beginners without technical jargon
- no advanced topics that intimidate or overwhelm beginners
Expand All @@ -52,12 +54,14 @@ On the homepage there is a compacted quick reference cheatsheet that includes mo

**Add-on libraries**

- **Utilities** — collections, datetime, random
- **Utilities** — collections, datetime, math, random, re, time
- **Data analysis** — csv, matplotlib, NumPy, pandas
- **APIs** — json, requests
- **Image editing** — Pillow
- **Computer vision** — OpenCV
- **Desktop UIs** — Tkinter
- **Games** — turtle
- **Testing** — pytest

## Site generator

Expand Down Expand Up @@ -110,6 +114,15 @@ A syntax highlighter, which colors code in the browser. It handles both the stat

A diagram renderer, which draws flowcharts and diagrams from a plain-text description. Fenced `mermaid` blocks in the Markdown are rendered to SVG on page load.

### Essentials / Advanced toggle

A two-option [switch](docs/javascripts/essentials_toggle.js) that lets a reader hide everything beyond a first-pass beginner curriculum. Content is opted into hiding by marking it `data-advanced="true"`:

- On a `##`/`###` heading inside a content page (e.g. functions.md's `## Decorators`), it hides that heading plus every sibling up to the next heading of the same or higher level, and removes the matching entry from the `toc.integrate` sidebar — so there's no dead nav link to something that's hidden.
- On a homepage card-grid row, it hides just that row; `data-advanced="card"` hides an entire homepage card instead, for a whole linked page rather than one section.

Each marking is independent — there's no shared list of "advanced" topics to keep in sync, just the attribute at each spot in the Markdown. State persists in `localStorage` and applies on every page (also settable via a `?simplified=true`/`false` URL param, for sharing a pre-set link). If a visible link points at a heading that's currently hidden (e.g. collections.md's cheat-sheet table linking to `#tuples`), following it flips the toggle back to Advanced and reveals the target instead of landing on nothing.

## Theme

### Custom CSS
Expand Down Expand Up @@ -171,13 +184,18 @@ The standard Python test runner, which discovers `test_*` functions across the r
because it needs editorial judgment a text-only check can't make.
- `tests/test_accessibility.py` is a static (no-browser) regression check for a specific
accessibility bug pattern (an `outline: none` with no `:focus-visible` replacement).
- `tests/test_typos.py` runs [codespell](#codespell) over the site's prose sources.
- The browser-based accessibility tier (`test_accessibility_browser.py`,
`test_accessibility_runnable.py`, `test_accessibility_keyboard.py`) renders real pages with
Playwright and checks: axe-core over representative pages in light/dark mode and at
mobile/tablet widths; the hand-wired Pyodide runnable blocks (accessible names, keyboard
focus order, the output live region); and keyboard navigation (skip link, a visible focus
ring on every tab stop, no positive tabindex, palette toggle reachable). It's the heaviest
part of the suite — needs `playwright install chromium` above and launches a real browser.
- `tests/test_essentials_toggle.py` is a browser test (same Playwright setup) for the
Essentials/Advanced toggle described above: the default (Advanced) state, that
`?simplified=true` hides marked content and carries onto a page's own heading + TOC entry,
and the link-recovery behavior for a visible link into hidden content.

### [Playwright](https://playwright.dev/)

Expand All @@ -187,6 +205,10 @@ A browser-automation library, which drives a real browser from code to load page

An accessibility rule engine, which scans a rendered page's DOM for WCAG violations. It runs inside the Playwright browser against every fully rendered page.

### [codespell](https://github.com/codespell-project/codespell)

A spell checker aimed at source code and prose, which flags known misspellings against a fixed list rather than words simply missing from a dictionary. `tests/test_typos.py` runs it over the site's page content and editorial docs.

### Continuous integration

1. Work is done on the `development` branch.
Expand Down
7 changes: 4 additions & 3 deletions STRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,10 @@ staying inline.**
bold/emphasis markup, not literal underscores, so `### Overriding __init__()` renders (and
slugifies) as "Overriding **init**()" with the underscores silently eaten. Confirm any heading
change like this against the real built HTML, not just the source Markdown.
- **`####` is reserved** for `index.md`'s homepage category boxes and genuinely deep
library-page content (e.g. `libraries/pillow.md`'s per-method sections) — most content pages
should never need to go past `###`.
- **`####` is a normal fourth level**, used under the same three conditions as `###` above, for
when a `###` section itself needs breaking down further (e.g. `types.md`'s `### int`/`### float`
each splitting into `#### Arithmetic`, `#### Convert`, etc.). Used throughout content pages, not
just `index.md`'s homepage category boxes or library pages.

### Homepage keyword deep-links (`index.md`, `libraries/index.md`)

Expand Down
19 changes: 19 additions & 0 deletions docs/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,25 @@ More about me at [lukasherman.com](https://lukasherman.com).

<div class="pfg-section" markdown="block">

## Other resources

This site isn't a comprehensive Python guide, so here's where to go for more.

For beginners:

- [W3Schools Python Tutorial](https://www.w3schools.com/python/) — syntax reference with a live editor for every example
- [Real Python](https://realpython.com/) — longer tutorials and articles that go deeper on individual topics
- [Python's own tutorial](https://docs.python.org/3/tutorial/) — official, terse, but authoritative

For more advanced Python:

- [Effective Python](https://effectivepython.com/) — specific, itemized advice on writing idiomatic, well-structured Python
- [PEP 8](https://peps.python.org/pep-0008/) — the official style guide

</div>

<div class="pfg-section" markdown="block">

## Helpful feedback

Spotted a mistake, or want to see something added? Let me know!
Expand Down
8 changes: 4 additions & 4 deletions docs/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ A **collection** is a single object that groups multiple values (like [basic typ
|------|---------|:-----------------:|:-------:|------------|
| <a href="#lists">**`list`**</a> | <pre><code class="language-python-ref">["ball", "burmese"]</code></pre> | position # | :material-check:{ .pt-icon-success } | <ul><li>An ordered group of items you can freely add to, remove from, or reorder</li><li>Not sure? Start here — the default, general-purpose choice</li></ul> |
| <a href="#dictionaries">**`dictionary "dict"`**</a> | <pre><code class="language-python-ref">{&#10; "species": "ball",&#10; "length_ft": 5&#10;}</code></pre> | Name of a key | :material-check:{ .pt-icon-success } | <ul><li>Values stored under names ("keys") instead of position, like `species`, `length_ft`</li><li>Use it to look values up by name</li><li>Can't have duplicate keys</li></ul> |
| <a href="#tuples">**`tuple`**</a> | <pre><code class="language-python-ref">("ball", "burmese")</code></pre> | position # | :material-close:{ .pt-icon-fail } | <ul><li>Like a list, but fixed — can't be changed once created</li><li>Values that should stay exactly as they are, like a coordinate pair</li></ul> |
| <a href="#tuples">**`tuple`**</a> | <pre><code class="language-python-ref">("ball", "burmese")</code></pre> | position # | :material-close:{ .pt-icon-fail } | <ul><li>Like a list, but it's sequence of items can't be changed once created</li><li>Values that should stay exactly as they are, like a coordinate pair</li></ul> |
| <a href="#sets">**`set`**</a> | <pre><code class="language-python-ref">{"ball", "burmese"}</code></pre> | Membership (`in`) | :material-check:{ .pt-icon-success } | <ul><li>An unordered group where duplicates are automatically dropped</li><li>Use it for fast "is this in here?" checks</li></ul> |

</div>
Expand All @@ -28,10 +28,10 @@ A **collection** is a single object that groups multiple values (like [basic typ
```python-ref
weights = [5, 3, 6]

type(weights) # <class 'list'>
type(weights) # <class 'list'>

isinstance(5, list) # True
isinstance(5, dict) # False
isinstance(weights, list) # True
isinstance(weights, dict) # False
```

<div class="pfg-section" markdown="block">
Expand Down
Loading
Loading