From a4ff8cc3e7b21914e31de6c36349bee48d47f787 Mon Sep 17 00:00:00 2001 From: Jiggly-Balls Date: Tue, 11 Aug 2026 17:32:47 +0530 Subject: [PATCH 1/6] Remove requirements.txt file --- requirements.txt | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 5a257e8..0000000 --- a/requirements.txt +++ /dev/null @@ -1,28 +0,0 @@ -# This file was autogenerated by uv via the following command: -# uv export --no-dev --no-hashes --no-emit-project -o requirements.txt -click==8.4.2 - # via zensical -colorama==0.4.6 ; sys_platform == 'win32' - # via click -deepmerge==2.1.0 - # via zensical -jinja2==3.1.6 - # via zensical -markdown==3.10.2 - # via - # pymdown-extensions - # zensical -markupsafe==3.0.3 - # via jinja2 -pygments==2.20.0 - # via zensical -pymdown-extensions==11.0.1 - # via zensical -pyyaml==6.0.3 - # via - # pymdown-extensions - # zensical -tomli==2.4.1 - # via zensical -zensical==0.0.51 - # via practical-python-docs From e8a1617fd793c01640e97bc8bcf60dda53498fe2 Mon Sep 17 00:00:00 2001 From: Jiggly-Balls Date: Tue, 11 Aug 2026 17:45:16 +0530 Subject: [PATCH 2/6] Added mdformat hook --- .mdformat.toml | 16 ++++++++++++++++ .pre-commit-config.yaml | 8 ++++++++ 2 files changed, 24 insertions(+) create mode 100644 .mdformat.toml diff --git a/.mdformat.toml b/.mdformat.toml new file mode 100644 index 0000000..3740e5e --- /dev/null +++ b/.mdformat.toml @@ -0,0 +1,16 @@ +wrap = "keep" +number = false +end_of_line = "lf" +validate = true +codeformatters = [ + "python", +] +exclude = [ + "CONTRIBUTING.md", + "README.md", + "venv/**", + "**/node_modules/**", + + # exclude all files that are not suffixed .md + "**/?", "**/??", "**/???", "**/*[!.]??", "**/*[!m]?", "**/*[!d]", +] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d460975..ad548b0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,3 +27,11 @@ repos: language: system pass_filenames: false files: ^(docs/|zensical\.toml|pyproject\.toml|uv\.lock) + + - repo: https://github.com/hukkin/mdformat + rev: 1.0.0 + hooks: + - id: mdformat + additional_dependencies: + - mdformat-mkdocs + - mdformat-ruff From 434ac4f9e783e41af71e581cf6272578c95b70ea Mon Sep 17 00:00:00 2001 From: Jiggly-Balls Date: Tue, 11 Aug 2026 17:48:46 +0530 Subject: [PATCH 3/6] Added makefile --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..27ea20c --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +.PHONY: run, strict, pre-commit + +all: run + +run: + uv run zensical serve + +strict: + uv run zensical build --strict + +pre-commit: + uv run --dev pre-commit run --all-files From 83b9176e365e06ec3b152145265e7760fa1fe1cd Mon Sep 17 00:00:00 2001 From: Jiggly-Balls Date: Tue, 11 Aug 2026 18:13:30 +0530 Subject: [PATCH 4/6] Added gfm mdformat extension --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad548b0..3e7349f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,3 +35,4 @@ repos: additional_dependencies: - mdformat-mkdocs - mdformat-ruff + - mdformat-gfm From 18d218127fd51e51756c864357d5e856ef103af6 Mon Sep 17 00:00:00 2001 From: Jiggly-Balls Date: Tue, 11 Aug 2026 19:43:28 +0530 Subject: [PATCH 5/6] Removed mdformat & added mdwrap --- .mdformat.toml | 16 ---------------- .pre-commit-config.yaml | 11 ++++------- 2 files changed, 4 insertions(+), 23 deletions(-) delete mode 100644 .mdformat.toml diff --git a/.mdformat.toml b/.mdformat.toml deleted file mode 100644 index 3740e5e..0000000 --- a/.mdformat.toml +++ /dev/null @@ -1,16 +0,0 @@ -wrap = "keep" -number = false -end_of_line = "lf" -validate = true -codeformatters = [ - "python", -] -exclude = [ - "CONTRIBUTING.md", - "README.md", - "venv/**", - "**/node_modules/**", - - # exclude all files that are not suffixed .md - "**/?", "**/??", "**/???", "**/*[!.]??", "**/*[!m]?", "**/*[!d]", -] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3e7349f..a1e037f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,11 +28,8 @@ repos: pass_filenames: false files: ^(docs/|zensical\.toml|pyproject\.toml|uv\.lock) - - repo: https://github.com/hukkin/mdformat - rev: 1.0.0 + - repo: https://github.com/swiss-ai-center/mdwrap + rev: 0.2.5 hooks: - - id: mdformat - additional_dependencies: - - mdformat-mkdocs - - mdformat-ruff - - mdformat-gfm + - id: mdwrap + args: [--print-width, "100", -i, "docs/resources/asking-good-questions.md", --fmt] From e1c58c5561594743e6f63647824d8fb4fd86c090 Mon Sep 17 00:00:00 2001 From: Jiggly-Balls Date: Tue, 11 Aug 2026 19:46:07 +0530 Subject: [PATCH 6/6] Formatting via mdwrap Formatting --- CONTRIBUTING.md | 59 +++++++------- README.md | 34 ++++----- docs/code-adventure/index.md | 21 +++-- docs/getting-started/index.md | 9 +-- docs/projects/build-something/beginner.md | 39 +++++----- docs/projects/build-something/index.md | 41 +++++----- docs/projects/build-something/intermediate.md | 54 ++++++------- docs/projects/index.md | 17 ++--- docs/projects/our-projects/eos.md | 76 +++++++++---------- docs/projects/our-projects/index.md | 30 ++++---- docs/projects/our-projects/this-site.md | 36 ++++----- docs/resources/asking-good-questions.md | 56 +++++++------- docs/resources/cheat-sheets.md | 21 +++-- docs/resources/getting-started.md | 68 ++++++++--------- docs/resources/index.md | 16 ++-- docs/resources/learning-path.md | 65 ++++++++-------- docs/rules/channels.md | 29 +++---- docs/rules/code-of-conduct.md | 33 ++++---- docs/rules/index.md | 69 ++++++++--------- docs/rules/moderation.md | 46 ++++++----- 20 files changed, 378 insertions(+), 441 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c3f3b8a..a013462 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,15 +1,14 @@ # Contributing -This site is written by members. Corrections, new resources and new project -challenges are all welcome. +This site is written by members. Corrections, new resources and new project challenges are all +welcome. - Collaborators branch directly and open a pull request from it. - All changes reach `main` through a pull request, which needs two approvals. - Branch names follow `feature/`, `bugfix/` or `chore/`, same as our other repos. -Local setup is in the [README](README.md). Run `uv run zensical build --strict` -before you push — a broken link fails the build, and it's faster to find out on -your machine. +Local setup is in the [README](README.md). Run `uv run zensical build --strict` before you push — a +broken link fails the build, and it's faster to find out on your machine. ## Adding a page @@ -20,14 +19,14 @@ Forgetting step 2 means your page builds but nobody can find it. ### Nav conventions -The nav is written out rather than derived from the folder structure. Zensical can -derive it, but it sorts alphabetically, which puts Projects ahead of Rules. +The nav is written out rather than derived from the folder structure. Zensical can derive it, but it +sorts alphabetically, which puts Projects ahead of Rules. - Every section's `index.md` comes first in its list. -- Everything after that goes in reading order — the page a newcomer needs first - goes first, not the one that's alphabetically luckiest. -- Nest a sub-group only when a section has two clear halves. `projects/` does. - Nothing else needs to. +- Everything after that goes in reading order — the page a newcomer needs first goes first, not the + one that's alphabetically luckiest. +- Nest a sub-group only when a section has two clear halves. `projects/` does. Nothing else needs + to. ### Front matter @@ -37,8 +36,8 @@ description: One sentence. Used by search engines and link previews. --- ``` -`description` is expected on every page. The landing page also uses -`hide: [navigation, toc]`; you probably don't need that anywhere else. +`description` is expected on every page. The landing page also uses `hide: [navigation, toc]`; you +probably don't need that anywhere else. ### Cross-links @@ -49,8 +48,8 @@ See [asking good questions](../resources/asking-good-questions.md). Link to a specific heading with [rule 6](../rules/index.md#6-post-code-as-code). ``` -Both the path and the anchor are checked at build time. A typo in either one -fails the build, which is the point. +Both the path and the anchor are checked at build time. A typo in either one fails the build, which +is the point. ### Admonitions @@ -60,8 +59,8 @@ fails the build, which is the point. Indented four spaces. ``` -`note`, `tip`, `warning`, `danger`, `info`, `example`, `question` and `failure` -all work. Use `???` instead of `!!!` to make it collapsible. +`note`, `tip`, `warning`, `danger`, `info`, `example`, `question` and `failure` all work. Use `???` +instead of `!!!` to make it collapsible. Don't stack three admonitions in a row. If everything is highlighted, nothing is. @@ -79,40 +78,36 @@ Good for per-platform instructions or two ways of doing one thing: Same. ``` -Tabs with matching labels switch together across the whole page, so keep the -labels consistent. +Tabs with matching labels switch together across the whole page, so keep the labels consistent. ### Tables -Tables beat bullet lists whenever each item has the same two or three -properties. Most of the pages here use them heavily; follow suit. +Tables beat bullet lists whenever each item has the same two or three properties. Most of the pages +here use them heavily; follow suit. ### Variables -Values that appear on more than one page live in `[project.extra]` in -`zensical.toml`: +Values that appear on more than one page live in `[project.extra]` in `zensical.toml`: ```markdown Join us at {{ discord_invite }}. ``` -Available: `discord_invite`, `eos_repo`, `site_repo`. Add more there rather than -pasting a URL into six pages. +Available: `discord_invite`, `eos_repo`, `site_repo`. Add more there rather than pasting a URL into +six pages. ### What not to add - No custom JavaScript. -- No CSS beyond `docs/stylesheets/extra.css`, and only for colour, font or the - landing page hero. +- No CSS beyond `docs/stylesheets/extra.css`, and only for colour, font or the landing page hero. - No images over a few hundred KB. Nobody's phone wants your 4 MB screenshot. ## Writing voice -This is the part reviewers actually comment on. Read a couple of existing pages -before you start and you'll pick it up faster than from any list. +This is the part reviewers actually comment on. Read a couple of existing pages before you start and +you'll pick it up faster than from any list. ## Reviewing -If you're reviewing, say which of these a comment is about: correctness, voice, -or preference. Preference comments are fine as long as they're labelled, so the -author knows they can decline. +If you're reviewing, say which of these a comment is about: correctness, voice, or preference. +Preference comments are fine as long as they're labelled, so the author knows they can decline. diff --git a/README.md b/README.md index 8e70a83..057595a 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,15 @@ Built with [Zensical](https://zensical.org/) ## Quick start -**Prerequisites:** [uv](https://docs.astral.sh/uv/getting-started/installation/). -It fetches the right Python for you, so that's the only thing to install. +**Prerequisites:** [uv](https://docs.astral.sh/uv/getting-started/installation/). It fetches the +right Python for you, so that's the only thing to install. ```bash uv sync uv run zensical serve ``` -That serves the site at `http://127.0.0.1:8000` and rebuilds when you save a -file. +That serves the site at `http://127.0.0.1:8000` and rebuilds when you save a file. ## Checking your work before you push @@ -23,11 +22,10 @@ file. uv run zensical build --strict ``` -Broken internal links and dead anchors are build failures, not warnings. CI runs -the same command, so if it passes here it passes there. +Broken internal links and dead anchors are build failures, not warnings. CI runs the same command, +so if it passes here it passes there. -Install the git hooks once and you'll get that check automatically on every -commit: +Install the git hooks once and you'll get that check automatically on every commit: ```bash uv run --dev pre-commit install @@ -62,25 +60,23 @@ zensical.toml all site configuration, including the nav 1. Create the Markdown file under the right folder in `docs/`. 2. Add it to the `nav` list in `zensical.toml`. -Step 2 isn't optional. Zensical can derive navigation from the folder structure, -but that sorts alphabetically and would put Projects ahead of Rules, so the nav -is written out. +Step 2 isn't optional. Zensical can derive navigation from the folder structure, but that sorts +alphabetically and would put Projects ahead of Rules, so the nav is written out. -[CONTRIBUTING.md](CONTRIBUTING.md) covers the writing conventions, which matter -more than the mechanics. +[CONTRIBUTING.md](CONTRIBUTING.md) covers the writing conventions, which matter more than the +mechanics. ## Deployment -Merging to `main` triggers `.github/workflows/deploy.yml`, which builds with -`--strict` and publishes to GitHub Pages. +Merging to `main` triggers `.github/workflows/deploy.yml`, which builds with `--strict` and +publishes to GitHub Pages. -Pull requests run `.github/workflows/ci.yml` — the same pre-commit checks you get -locally. +Pull requests run `.github/workflows/ci.yml` — the same pre-commit checks you get locally. ## Dependencies -One direct dependency, `zensical`, pinned through `uv.lock`. `requirements.txt` is -generated from the lockfile for anyone who wants to read the tree without uv: +One direct dependency, `zensical`, pinned through `uv.lock`. `requirements.txt` is generated from +the lockfile for anyone who wants to read the tree without uv: ```bash uv export --no-dev --no-hashes --no-emit-project -o requirements.txt diff --git a/docs/code-adventure/index.md b/docs/code-adventure/index.md index 5516944..11c6b0a 100644 --- a/docs/code-adventure/index.md +++ b/docs/code-adventure/index.md @@ -7,21 +7,21 @@ description: A story-based series of Programming Puzzles inspired by Advent of C [![Practical Python Code Adventure](/static/code-adventure/MAINlight.png#only-light)](#adventures) [![Practical Python Code Adventure](/static/code-adventure/MAINdark.png#only-dark)](#adventures) -Practical Python Code Adventure is a series of programming puzzles inspired by Eric Wastl's *Advent of Code*. +Practical Python Code Adventure is a series of programming puzzles inspired by Eric Wastl's +*Advent of Code*. -Each year features __10 story-driven puzzles__ designed to teach programming concepts, popular algorithms, -and real topics from mathematics and science. Every puzzle has two parts, with the second building on the first -to provide an extra challenge. As you progress, the story unfolds alongside the puzzles, adding another layer -of mystery and satisfaction to each solution. +Each year features __10 story-driven puzzles__ designed to teach programming concepts, popular +algorithms, and real topics from mathematics and science. Every puzzle has two parts, with the +second building on the first to provide an extra challenge. As you progress, the story unfolds +alongside the puzzles, adding another layer of mystery and satisfaction to each solution. -The puzzles are __free for everyone to enjoy__. Signing in with Discord is optional and lets you save your -progress, but you are also welcome to play as a guest. For the best experience, we recommend completing the -puzzles in order so the story develops naturally, though you're free to tackle them in any order or skip a -puzzle if it proves too challenging. +The puzzles are __free for everyone to enjoy__. Signing in with Discord is optional and lets you +save your progress, but you are also welcome to play as a guest. For the best experience, we +recommend completing the puzzles in order so the story develops naturally, though you're free to +tackle them in any order or skip a puzzle if it proves too challenging. Do you love solving puzzles and learning something new? __Join us on a Code Adventure!__ - ## :octicons-trophy-24:{ .md .middle } Adventures
@@ -55,7 +55,6 @@ Do you love solving puzzles and learning something new? __Join us on a Code Adve
- !!! tip "" ## :material-campfire:{ .lg .middle } Around the campfire :material-campfire:{ .lg .middle .flip } diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 8f47523..f0859a8 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -4,7 +4,8 @@ description: A guide for new people # Welcome -For those who are looking to get started with Python, or to simply be a part of a python community, this is the place to be. +For those who are looking to get started with Python, or to simply be a part of a python community, +this is the place to be.
- :material-book-open-variant:{ .lg .middle } __Resources__ @@ -39,9 +40,7 @@ For those who are looking to get started with Python, or to simply be a part of
- ## Contributing to either -Both halves take pull requests. Adding a challenge is the easiest first contribution -to this site — see [contributing](../projects/our-projects/this-site.md) for how -the site is built. +Both halves take pull requests. Adding a challenge is the easiest first contribution to this site — +see [contributing](../projects/our-projects/this-site.md) for how the site is built. diff --git a/docs/projects/build-something/beginner.md b/docs/projects/build-something/beginner.md index 82b067a..7ad3862 100644 --- a/docs/projects/build-something/beginner.md +++ b/docs/projects/build-something/beginner.md @@ -4,13 +4,12 @@ description: Three project challenges for people who know the basics and haven't # Beginner challenges -You know loops, functions, lists and dictionaries. Nothing here needs a -dependency. +You know loops, functions, lists and dictionaries. Nothing here needs a dependency. ## Unit converter -**Goal.** A command-line tool that converts between units — temperature, length, -mass, pick two or more categories. +**Goal.** A command-line tool that converts between units — temperature, length, mass, pick two or +more categories. **Done when:** @@ -19,21 +18,20 @@ mass, pick two or more categories. - [ ] Typing nonsense produces a helpful message, not a traceback. - [ ] Converting a value and converting it back gives you the original number. -**Stretch.** Accept arguments so `convert 100 c f` works without prompting. Add -`argparse`. Support unit aliases, so `celsius`, `c` and `C` all work. +**Stretch.** Accept arguments so `convert 100 c f` works without prompting. Add `argparse`. Support +unit aliases, so `celsius`, `c` and `C` all work. **Time.** An evening. !!! tip "The interesting part" - The conversions are arithmetic. The design question is how you store the - units so adding a new one doesn't mean writing another `if`. Try a dictionary - before you try a class. + The conversions are arithmetic. The design question is how you store the units so adding a new one + doesn't mean writing another `if`. Try a dictionary before you try a class. ## Todo list that survives restarting -**Goal.** Add, list, complete and delete tasks, with the list still there after -you close the program. +**Goal.** Add, list, complete and delete tasks, with the list still there after you close the +program. **Done when:** @@ -42,8 +40,8 @@ you close the program. - [ ] Deleting task 3 doesn't renumber the others in a way that surprises you. - [ ] Starting with no data file works instead of crashing. -**Stretch.** Due dates. Priorities and sorting. Swap your file format for -`sqlite3` from the standard library. +**Stretch.** Due dates. Priorities and sorting. Swap your file format for `sqlite3` from the +standard library. **Time.** A weekend. @@ -65,15 +63,14 @@ you close the program. === "Storing it as CSV" - Simpler to append to, worse at nested data. Use `csv.DictReader` rather than - splitting on commas yourself — quoting will bite you otherwise. + Simpler to append to, worse at nested data. Use `csv.DictReader` rather than splitting on commas + yourself — quoting will bite you otherwise. ## Guess-the-number, properly **Goal.** The classic, done well. The program picks a number and you guess it. -Everyone writes this in ten minutes and then discovers the interesting version -takes longer. +Everyone writes this in ten minutes and then discovers the interesting version takes longer. **Done when:** @@ -83,13 +80,11 @@ takes longer. - [ ] It offers a rematch without restarting the program. - [ ] High scores persist between runs. -**Stretch.** Reverse it — you pick, the computer guesses, and it plays optimally. -Then explain to yourself why binary search never needs more than seven guesses -for 1 to 100. +**Stretch.** Reverse it — you pick, the computer guesses, and it plays optimally. Then explain to +yourself why binary search never needs more than seven guesses for 1 to 100. **Time.** An evening, then another one for the reverse mode. ## Next -When one of these stops feeling difficult, move to the -[intermediate challenges](intermediate.md). +When one of these stops feeling difficult, move to the [intermediate challenges](intermediate.md). diff --git a/docs/projects/build-something/index.md b/docs/projects/build-something/index.md index c3aeac1..ff58480 100644 --- a/docs/projects/build-something/index.md +++ b/docs/projects/build-something/index.md @@ -4,22 +4,22 @@ description: Project challenges with a defined scope, sorted by difficulty. # Build something -"Build a project" is advice that helps nobody. These are challenges: a target, a -definition of finished, and no solution. +"Build a project" is advice that helps nobody. These are challenges: a target, a definition of +finished, and no solution. ## How a challenge works Every challenge has the same four parts. -| Part | Means | -|------|-------| -| **Goal** | One sentence on what the thing does | -| **Done when** | The checklist that decides whether you've finished | -| **Stretch** | Optional extras, roughly in order of difficulty | -| **Time** | A rough estimate for someone at that level, assuming they get stuck twice | +| Part | Means | +|---------------|---------------------------------------------------------------------------| +| **Goal** | One sentence on what the thing does | +| **Done when** | The checklist that decides whether you've finished | +| **Stretch** | Optional extras, roughly in order of difficulty | +| **Time** | A rough estimate for someone at that level, assuming they get stuck twice | -The time estimate is a guide, not a target. Taking three times as long is normal -and isn't a signal about you. +The time estimate is a guide, not a target. Taking three times as long is normal and isn't a signal +about you. ## Levels @@ -47,21 +47,20 @@ and isn't a signal about you. ## Rules of the exercise -- Use the standard library first. Reach for a dependency when the standard - library actually can't do it. +- Use the standard library first. Reach for a dependency when the standard library actually can't do + it. - Write it badly, then fix it. A working ugly version beats an elegant plan. - Post it in the showcase channel when it works, even if you think it's small. !!! tip "Stuck is the point" - A challenge you can finish without getting stuck was too easy. When you do get - stuck, [ask well](../../resources/asking-good-questions.md) and say which - challenge you're on. + A challenge you can finish without getting stuck was too easy. When you do get stuck, + [ask well](../../resources/asking-good-questions.md) and say which challenge you're on. ## If none of these appeal -challenges here are deliberately few. When you want a longer list, or something in a -specific direction: +challenges here are deliberately few. When you want a longer list, or something in a specific +direction: | Where | What you'll find | |-------|------------------| @@ -71,10 +70,10 @@ specific direction: !!! warning "Reading the solution isn't building it" - The first two links include working code. Looking at it before you've tried - costs you the entire exercise. + The first two links include working code. Looking at it before you've tried costs you the entire + exercise. ## Adding a challenge -Open a pull request. Keep the four parts, don't include a solution, and make sure -"done when" is something a reader can check for themselves. +Open a pull request. Keep the four parts, don't include a solution, and make sure "done when" is +something a reader can check for themselves. diff --git a/docs/projects/build-something/intermediate.md b/docs/projects/build-something/intermediate.md index 42fb14e..10d3cd6 100644 --- a/docs/projects/build-something/intermediate.md +++ b/docs/projects/build-something/intermediate.md @@ -4,16 +4,16 @@ description: challenges for people who can finish a project and want structure, # Intermediate challenges -You've built something that works. These are about structure, error handling and -code someone else can read. +You've built something that works. These are about structure, error handling and code someone else +can read. -Each of these needs more than one module. If yours is one long file, that's the -first thing the brief is teaching you. +Each of these needs more than one module. If yours is one long file, that's the first thing the +brief is teaching you. ## HTTP API client with a cache -**Goal.** A small library that wraps a public API and caches responses so you -don't re-request the same thing. +**Goal.** A small library that wraps a public API and caches responses so you don't re-request the +same thing. Pick an API with no authentication — there are plenty of open ones. @@ -23,19 +23,17 @@ Pick an API with no authentication — there are plenty of open ones. - [ ] The cache expires after a configurable interval. - [ ] Network failures raise something your caller can catch and understand. - [ ] Tests pass with no network access at all. -- [ ] The public interface is documented well enough for someone to use without - reading the source. +- [ ] The public interface is documented well enough for someone to use without reading the source. -**Stretch.** Cache to disk instead of memory. Add retries with backoff. Rewrite -it with `httpx` and `async`, and measure whether it actually got faster. +**Stretch.** Cache to disk instead of memory. Add retries with backoff. Rewrite it with `httpx` and +`async`, and measure whether it actually got faster. **Time.** A week of evenings. !!! warning "The test requirement is the hard part" - Testing without network access forces you to separate "fetch" from "decide - whether to fetch". If you can't test it offline, the design needs changing — - which is the lesson. + Testing without network access forces you to separate "fetch" from "decide whether to fetch". If you + can't test it offline, the design needs changing — which is the lesson. ## Log file analyser @@ -49,8 +47,8 @@ it with `httpx` and `async`, and measure whether it actually got faster. - [ ] It has a `--json` mode for machine-readable output. - [ ] Running it on an empty file produces an empty report, not a crash. -**Stretch.** Multiple log formats via a plugin structure. Streaming from stdin so -it works in a pipe. Charts, if you can do it without making the tool worse. +**Stretch.** Multiple log formats via a plugin structure. Streaming from stdin so it works in a +pipe. Charts, if you can do it without making the tool worse. **Time.** A week of evenings. @@ -65,8 +63,8 @@ it works in a pipe. Charts, if you can do it without making the tool worse. yield entry ``` - A generator keeps memory flat regardless of file size, and composes with - `itertools` and `collections.Counter`. + A generator keeps memory flat regardless of file size, and composes with `itertools` and + `collections.Counter`. === "Reading it all in" @@ -74,13 +72,13 @@ it works in a pipe. Charts, if you can do it without making the tool worse. lines = open(path).read().splitlines() ``` - Fine for a 2 MB file, a problem at 2 GB. Try it on something large once so - the failure mode is familiar rather than theoretical. + Fine for a 2 MB file, a problem at 2 GB. Try it on something large once so the failure mode is + familiar rather than theoretical. ## Discord bot cog -**Goal.** Add a feature to [Eos](../our-projects/eos.md) — or your own bot, if -you'd rather not open a pull request yet. +**Goal.** Add a feature to [Eos](../our-projects/eos.md) — or your own bot, if you'd rather not open +a pull request yet. This is the brief most likely to end with your code running in the server. @@ -92,19 +90,17 @@ This is the brief most likely to end with your code running in the server. - [ ] No blocking calls in an async function. No `time.sleep`. - [ ] Permissions are checked where they matter. -**Stretch.** Add persistence via a new API route. Write tests for the helper -functions. Handle Discord's rate limits properly under load. +**Stretch.** Add persistence via a new API route. Write tests for the helper functions. Handle +Discord's rate limits properly under load. **Time.** A weekend, plus review time if you open a pull request. !!! tip "Read one first" - Pick an existing cog in `src/bot/cogs/features/` and follow it end to end - before writing yours. The patterns are consistent, and matching them is most - of passing review. + Pick an existing cog in `src/bot/cogs/features/` and follow it end to end before writing yours. The + patterns are consistent, and matching them is most of passing review. ## Where next -There isn't an advanced page yet. At this point the useful next step is -maintaining something real — pick an issue on -[one of our projects](../our-projects/index.md) and work with a reviewer. +There isn't an advanced page yet. At this point the useful next step is maintaining something real — +pick an issue on [one of our projects](../our-projects/index.md) and work with a reviewer. diff --git a/docs/projects/index.md b/docs/projects/index.md index c8786e5..325638f 100644 --- a/docs/projects/index.md +++ b/docs/projects/index.md @@ -4,8 +4,8 @@ description: Software the community maintains, and briefs to build your own. # Projects -Two different things live here. One is documentation for software this community -runs. The other is a set of briefs for people who want something to build. +Two different things live here. One is documentation for software this community runs. The other is +a set of briefs for people who want something to build.
@@ -31,14 +31,13 @@ runs. The other is a set of briefs for people who want something to build. ## Why briefs instead of tutorials -Tutorials give you working code and the illusion of understanding. A brief gives -you a target and leaves the middle to you, which is where the learning is. +Tutorials give you working code and the illusion of understanding. A brief gives you a target and +leaves the middle to you, which is where the learning is. -Every brief states what it should do, what counts as finished, and roughly how -long it takes. None of them include the solution. +Every brief states what it should do, what counts as finished, and roughly how long it takes. None +of them include the solution. ## Contributing to either -Both halves take pull requests. Adding a brief is the easiest first contribution -to this site — see [contributing](../projects/our-projects/this-site.md) for how -the site is built. +Both halves take pull requests. Adding a brief is the easiest first contribution to this site — see +[contributing](../projects/our-projects/this-site.md) for how the site is built. diff --git a/docs/projects/our-projects/eos.md b/docs/projects/our-projects/eos.md index 0b1518b..1f352a7 100644 --- a/docs/projects/our-projects/eos.md +++ b/docs/projects/our-projects/eos.md @@ -4,8 +4,8 @@ description: The Discord bot that runs the server — architecture, setup, and h # Eos -Eos is the bot that handles verification, moderation, logging and points on the -server. Source lives at [{{ eos_repo }}]({{ eos_repo }}). +Eos is the bot that handles verification, moderation, logging and points on the server. Source lives +at [{{ eos_repo }}]({{ eos_repo }}). ## Architecture @@ -15,18 +15,18 @@ Three services, talking in one direction: discord.py bot <-> Flask API <-> Postgres ``` -The bot never touches the database. It calls the API, which owns all the SQL. -That split means you can work on bot behaviour without knowing the schema, and -change the schema without touching the bot. +The bot never touches the database. It calls the API, which owns all the SQL. That split means you +can work on bot behaviour without knowing the schema, and change the schema without touching the +bot. -| Component | Location | Notes | -|-----------|----------|-------| -| Bot | `src/bot/` | Cogs grouped by purpose: `admin/`, `features/`, `logging/`, `moderation/`, `verification/` | -| API | `src/api/` | Flask. Routes in `src/api/routes/`, database access wrapped in `src/api/core/db_helper.py` | -| Database | `src/db/` | `init.sql` runs on first start; `migrations.sql` is applied by a migration service on every boot | +| Component | Location | Notes | +|-----------|------------|--------------------------------------------------------------------------------------------------| +| Bot | `src/bot/` | Cogs grouped by purpose: `admin/`, `features/`, `logging/`, `moderation/`, `verification/` | +| API | `src/api/` | Flask. Routes in `src/api/routes/`, database access wrapped in `src/api/core/db_helper.py` | +| Database | `src/db/` | `init.sql` runs on first start; `migrations.sql` is applied by a migration service on every boot | -The bot's HTTP calls are wrapped in `src/bot/core/api_helper.py`, so individual -cogs don't build requests by hand. +The bot's HTTP calls are wrapped in `src/bot/core/api_helper.py`, so individual cogs don't build +requests by hand. ## Running it @@ -39,28 +39,24 @@ cogs don't build requests by hand. $ cp .env.EXAMPLE .env ``` - Set your token and `MASTER_GUILD` — the ID of the guild the bot treats as - home — then: + Set your token and `MASTER_GUILD` — the ID of the guild the bot treats as home — then: ```console $ docker compose up -d ``` - The bot should come online. Run `>hc` in the server to healthcheck the API - and database. + The bot should come online. Run `>hc` in the server to healthcheck the API and database. !!! warning "Port 5432 is often taken" - If you already run Postgres locally, change `POSTGRES_PORT_HOST` in - `.env` to something free, usually `5433`, and rebuild with - `docker compose up -d --build`. `POSTGRES_PORT` is the in-container + If you already run Postgres locally, change `POSTGRES_PORT_HOST` in `.env` to something free, + usually `5433`, and rebuild with `docker compose up -d --build`. `POSTGRES_PORT` is the in-container port and shouldn't change. === "Locally with uv" - Faster for iterating on one service. The repo is a - [uv](https://docs.astral.sh/uv/) workspace with two members, `eos-api` and - `eos-bot`: + Faster for iterating on one service. The repo is a [uv](https://docs.astral.sh/uv/) workspace with + two members, `eos-api` and `eos-bot`: ```console $ uv sync @@ -73,25 +69,22 @@ cogs don't build requests by hand. $ uv add --package eos-bot some-library ``` - The bot still needs the API reachable and a populated `src/.env`. The usual - arrangement is Postgres and the API in Docker while you run the service - you're editing on the host. + The bot still needs the API reachable and a populated `src/.env`. The usual arrangement is Postgres + and the API in Docker while you run the service you're editing on the host. ## Points -Points are awarded automatically. Sending a message earns points based on its -word count; deleting one takes them back off. Joining adds you to the table, -leaving removes you. +Points are awarded automatically. Sending a message earns points based on its word count; deleting +one takes them back off. Joining adds you to the table, leaving removes you. -| Command | Does | Who can run it | -|---------|------|----------------| -| `>top_10` | Shows the leaderboard | Anyone | -| `>get_points @user` | Shows one member's points | Anyone | +| Command | Does | Who can run it | +|---------------------------------|-----------------------------------------|------------------------| +| `>top_10` | Shows the leaderboard | Anyone | +| `>get_points @user` | Shows one member's points | Anyone | | `>update_points @user ` | Adds or subtracts. Negative to subtract | Admin, home guild only | -The full command reference — moderation, settings, verification, healthchecks — -is in the repository README rather than duplicated here, because it changes with -the code. +The full command reference — moderation, settings, verification, healthchecks — is in the repository +README rather than duplicated here, because it changes with the code. ## Contributing @@ -100,17 +93,16 @@ Read `CONTRIBUTING.md` in the repo first. The essentials: - Collaborators branch directly. Everyone else forks. - Branch names follow `feature/`, `bugfix/` or `chore/` prefixes. - All changes reach `master` through a pull request with one approval. -- Install the hooks once with `uv run --dev pre-commit install`. The same checks - run in CI, so this only saves you a round trip. +- Install the hooks once with `uv run --dev pre-commit install`. The same checks run in CI, so this + only saves you a round trip. !!! tip "Where to start reading" - Pick a cog in `src/bot/cogs/` and follow one command end to end — cog to - `api_helper`, to a route, to `db_helper`. It's a small trip and it explains - the whole codebase. + Pick a cog in `src/bot/cogs/` and follow one command end to end — cog to `api_helper`, to a route, + to `db_helper`. It's a small trip and it explains the whole codebase. ## Related -- [Moderation](../../rules/moderation.md) — what the automatic enforcement does, - from a member's point of view. +- [Moderation](../../rules/moderation.md) — what the automatic enforcement does, from a member's + point of view. - [This site](this-site.md) — the other thing we maintain. diff --git a/docs/projects/our-projects/index.md b/docs/projects/our-projects/index.md index 5fb64d5..633acdb 100644 --- a/docs/projects/our-projects/index.md +++ b/docs/projects/our-projects/index.md @@ -4,31 +4,29 @@ description: Software this community builds and runs. # Our projects -Everything here is real software running in production, maintained by community -members. Contributions are welcome and reviewed by people you can talk to. +Everything here is real software running in production, maintained by community members. +Contributions are welcome and reviewed by people you can talk to. -| Project | What it is | Stack | -|---------|-----------|-------| -| [Eos](eos.md) | The Discord bot that runs the server | discord.py, Flask, Postgres, Docker | -| [This site](this-site.md) | The documentation you're reading | Zensical, uv, GitHub Pages | +| Project | What it is | Stack | +|---------------------------|--------------------------------------|-------------------------------------| +| [Eos](eos.md) | The Discord bot that runs the server | discord.py, Flask, Postgres, Docker | +| [This site](this-site.md) | The documentation you're reading | Zensical, uv, GitHub Pages | ## How contributing works !!! tip "Join us!" - If you'd like to contribute, let us know, and we can add you to the Org! - For now, we are not accepting contributions from outside the Org. + If you'd like to contribute, let us know, and we can add you to the Org! For now, we are not + accepting contributions from outside the Org. -Both projects use the same flow: branch, open a pull request, get -approvals, merge. Both have issues labelled for newcomers. +Both projects use the same flow: branch, open a pull request, get approvals, merge. Both have issues +labelled for newcomers. !!! tip "Start by running it" - Get the project building locally before you pick an issue. Half of a first - contribution is understanding the setup, and it's much easier to ask about - that in advance than halfway through a pull request. If you need help, ask in - the Discord server! + Get the project building locally before you pick an issue. Half of a first contribution is + understanding the setup, and it's much easier to ask about that in advance than halfway through a + pull request. If you need help, ask in the Discord server! ## Suggesting a new project -Bring it up in the server! Things that get adopted usually -solve a problem, or do something cool +Bring it up in the server! Things that get adopted usually solve a problem, or do something cool diff --git a/docs/projects/our-projects/this-site.md b/docs/projects/our-projects/this-site.md index ec9c50e..4fade0c 100644 --- a/docs/projects/our-projects/this-site.md +++ b/docs/projects/our-projects/this-site.md @@ -4,22 +4,21 @@ description: How this documentation site is built, checked and deployed. # This site -The site you're reading. Markdown in, static HTML out, deployed by CI when -something lands on `main`. Source at [{{ site_repo }}]({{ site_repo }}). +The site you're reading. Markdown in, static HTML out, deployed by CI when something lands on +`main`. Source at [{{ site_repo }}]({{ site_repo }}). ## Stack -| Piece | What it does | -|-------|--------------| +| Piece | What it does | +|-----------------------------------|----------------------------------------------------------------------------------------------------| | [Zensical](https://zensical.org/) | Static site generator, by the Material for MkDocs team. Search, navigation and macros are built in | -| [uv](https://docs.astral.sh/uv/) | Dependency management. Versions are pinned in `uv.lock` | -| pre-commit | Formatting, typo and build checks before a commit lands | -| GitHub Actions | Builds on every pull request, deploys on merge to `main` | -| GitHub Pages | Hosting, with a custom domain | +| [uv](https://docs.astral.sh/uv/) | Dependency management. Versions are pinned in `uv.lock` | +| pre-commit | Formatting, typo and build checks before a commit lands | +| GitHub Actions | Builds on every pull request, deploys on merge to `main` | +| GitHub Pages | Hosting, with a custom domain | -There is one dependency, `zensical`, and it brings eight transitive packages with -it. That's deliberate — the plugin list this site would have needed under MkDocs -is all built in. +There is one dependency, `zensical`, and it brings eight transitive packages with it. That's +deliberate — the plugin list this site would have needed under MkDocs is all built in. ## Running it locally @@ -28,8 +27,7 @@ $ uv sync $ uv run zensical serve ``` -That serves on `http://127.0.0.1:8000` and rebuilds when you save. To check what -CI will check: +That serves on `http://127.0.0.1:8000` and rebuilds when you save. To check what CI will check: ```console $ uv run zensical build --strict @@ -37,9 +35,9 @@ $ uv run zensical build --strict !!! warning "--strict is the gate" - Broken internal links and dead anchors are build failures, not warnings. If - a link to `resources/getting-started.md` has a typo, the build fails and the - deploy never happens. Run it before you push. + Broken internal links and dead anchors are build failures, not warnings. If a link to + `resources/getting-started.md` has a typo, the build fails and the deploy never happens. Run it + before you push. ## Adding a page @@ -53,13 +51,11 @@ covers the writing conventions, which matter more than the mechanics. ## Deployment -Merging to `main` triggers a workflow that builds the site and publishes it to -GitHub Pages. There's no manual step. -PRs to main require at least 2 approving reviews from verified contributors. +Merging to `main` triggers a workflow that builds the site and publishes it to GitHub Pages. There's +no manual step. PRs to main require at least 2 approving reviews from verified contributors. Pull requests run with `--strict`, plus the pre-commit checks. - ## Related - [Eos](eos.md) — the other project, and considerably more moving parts. diff --git a/docs/resources/asking-good-questions.md b/docs/resources/asking-good-questions.md index 1e527f2..6bb61b0 100644 --- a/docs/resources/asking-good-questions.md +++ b/docs/resources/asking-good-questions.md @@ -4,8 +4,8 @@ description: How to ask so that someone can actually answer. # Asking good questions -A good question gets answered in minutes. A bad one sits there while people read -it, sigh, and scroll past. Laziness is not a virtue. +A good question gets answered in minutes. A bad one sits there while people read it, sigh, and +scroll past. Laziness is not a virtue. ## The short version @@ -20,10 +20,10 @@ That's it. Most unanswered questions are missing number three. ## Post the whole traceback -Not the last line. The whole thing, from `Traceback (most recent call last)` -down. The useful information is usually in the middle. +Not the last line. The whole thing, from `Traceback (most recent call last)` down. The useful +information is usually in the middle. -```python +``` Traceback (most recent call last): File "shopping.py", line 12, in total = sum(prices) @@ -34,15 +34,14 @@ Traceback (most recent call last): TypeError: unsupported operand type(s) for +: 'int' and 'str' ``` -That tells a helper the bug is in your `sum`, that one of your prices is a -string, and which line to look at. "I get a TypeError" tells them nothing. +That tells a helper the bug is in your `sum`, that one of your prices is a string, and which line to +look at. "I get a TypeError" tells them nothing. ## Format your code -Use a fenced block with a language tag. In Discord, three backticks and the -language: +Use a fenced block with a language tag. In Discord, three backticks and the language: -````text +```` ```python prices = ["4.99", 3.50] print(sum(prices)) @@ -51,18 +50,18 @@ print(sum(prices)) !!! failure "Not screenshots" - [Rule 7](../rules/index.md#7-ask-effective-questions) asks for code as text - because helpers need to run your code. Nobody is retyping your program from a - photograph, and screen readers can't read it at all. + [Rule 7](../rules/index.md#7-ask-effective-questions) asks for code as text because helpers need to + run your code. Nobody is retyping your program from a photograph, and screen readers can't read it + at all. ## Cut it down first -Post the smallest program that still shows the problem. Deleting code until the -bug disappears tells you where the bug is — you'll often solve it yourself before -you finish, which is the best possible outcome. +Post the smallest program that still shows the problem. Deleting code until the bug disappears tells +you where the bug is — you'll often solve it yourself before you finish, which is the best possible +outcome. -If your file is 400 lines and you don't know which part is broken, say so, and -post the part you suspect. +If your file is 400 lines and you don't know which part is broken, say so, and post the part you +suspect. ??? example "Before and after" @@ -82,22 +81,21 @@ post the part you suspect. ## Say what you already tried -It stops people suggesting it again, and it tells them how you think. "I checked -the type with `print(type(prices[0]))` and it's a string, but I don't see where it -became one" is a question someone will enjoy answering. +It stops people suggesting it again, and it tells them how you think. "I checked the type with +`print(type(prices[0]))` and it's a string, but I don't see where it became one" is a question +someone will enjoy answering. ## Things that slow you down -| Don't | Why | -|-------|-----| -| "Does anyone know Python?" | Obviously not, this is a server about snakes after all. Ask the actual question. Get on with it. | -| "Can someone DM me?" | No, that's so much mmore effort than just asking the question. | -| Pinging a specific person | Are you in a conversation with that person? Do you know them? No? Don't ping. | -| Deleting your question after it's solved | The next person with your bug wanted to read it, and it makes the chat lame. | +| Don't | Why | +|------------------------------------------|--------------------------------------------------------------------------------------------------| +| "Does anyone know Python?" | Obviously not, this is a server about snakes after all. Ask the actual question. Get on with it. | +| "Can someone DM me?" | No, that's so much more effort than just asking the question. | +| Pinging a specific person | Are you in a conversation with that person? Do you know them? No? Don't ping. | +| Deleting your question after it's solved | The next person with your bug wanted to read it, and it makes the chat lame. | ## After you get an answer -Say whether it worked. Helpers are debugging blind, and "that fixed it" is the -only signal they get. +Say whether it worked. Helpers are debugging blind, and "that fixed it" is the only signal they get. If it didn't work, say what happened instead. diff --git a/docs/resources/cheat-sheets.md b/docs/resources/cheat-sheets.md index 534f74a..26b748e 100644 --- a/docs/resources/cheat-sheets.md +++ b/docs/resources/cheat-sheets.md @@ -4,8 +4,8 @@ description: Quick references and small tools worth keeping in a browser tab. # Cheat sheets and tools -Things you look at for thirty seconds and then close. None of this teaches you -Python — it saves you from re-learning the same syntax every few weeks. +Things you look at for thirty seconds and then close. None of this teaches you Python — it saves you +from re-learning the same syntax every few weeks. ## Quick reference @@ -32,22 +32,21 @@ Python — it saves you from re-learning the same syntax every few weeks. | [pyreadiness.org](https://pyreadiness.org/) | A package won't install and you suspect your Python version is too new | | [Visual TK](https://visualtk.com/) | Laying out a `tkinter` window by dragging, then taking the generated code as a starting point | -Treat generated GUI code as a first draft. It gets a window on screen; it won't -be organised the way you'd organise it. +Treat generated GUI code as a first draft. It gets a window on screen; it won't be organised the way +you'd organise it. ## Learning git Git isn't Python, and it will still take up a week of your life eventually. -[Learn Git Branching](https://learngitbranching.js.org/) is the best free -introduction we know of. It draws the commit graph as you type real commands, -which turns `rebase` and `merge` from incantations into something you can see. +[Learn Git Branching](https://learngitbranching.js.org/) is the best free introduction we know of. +It draws the commit graph as you type real commands, which turns `rebase` and `merge` from +incantations into something you can see. -Do the "Introduction Sequence" before your first pull request and most of the -scary parts of git stop being scary. +Do the "Introduction Sequence" before your first pull request and most of the scary parts of git +stop being scary. ## Where to go next The [learning path](learning-path.md) has material sorted by level, and the -[project briefs](../projects/build-something/index.md) give you something to -point all this at. +[project briefs](../projects/build-something/index.md) give you something to point all this at. diff --git a/docs/resources/getting-started.md b/docs/resources/getting-started.md index acf0a5c..b9d427c 100644 --- a/docs/resources/getting-started.md +++ b/docs/resources/getting-started.md @@ -4,18 +4,18 @@ description: Install Python, pick an editor, and understand virtual environments # Getting started -Get a working Python and an editor that helps you. Half the questions in the help -channels are environment problems wearing a costume. +Get a working Python and an editor that helps you. Half the questions in the help channels are +environment problems wearing a costume. ## Install Python -Get 3.12 or newer. I'd avoid any version of python that isn't in the [latest stable release](https://devguide.python.org/versions/). +Get 3.12 or newer. I'd avoid any version of python that isn't in the +[latest stable release](https://devguide.python.org/versions/). === "Windows" - Install from [python.org](https://www.python.org/downloads/). Tick **Add - python.exe to PATH** in the installer — it's off by default and it's the - single most common cause of "python is not recognized". + Install from [python.org](https://www.python.org/downloads/). Tick **Add python.exe to PATH** in the + installer — it's off by default and it's the single most common cause of "python is not recognized". Verify it, using the `py` launcher that ships with the Windows installer: @@ -26,8 +26,8 @@ Get 3.12 or newer. I'd avoid any version of python that isn't in the [latest sta !!! warning "Skip the Microsoft Store version" - It works, mostly, until it doesn't. Its sandboxing breaks tools that - expect to write next to the interpreter. + It works, mostly, until it doesn't. Its sandboxing breaks tools that expect to write next to the + interpreter. === "macOS" @@ -40,28 +40,26 @@ Get 3.12 or newer. I'd avoid any version of python that isn't in the [latest sta Python 3.13.14 ``` - Or download the installer from - [python.org](https://www.python.org/downloads/) if you'd rather not add a - package manager. + Or download the installer from [python.org](https://www.python.org/downloads/) if you'd rather not + add a package manager. === "Linux" - Your distribution has a Python, and it's probably fine for scripts. For - anything you plan to keep, install a version you control: + Your distribution has a Python, and it's probably fine for scripts. For anything you plan to keep, + install a version you control: ```console $ sudo apt install python3.13 python3.13-venv # Debian, Ubuntu $ sudo dnf install python3.13 # Fedora ``` - The `-venv` package is separate on Debian and Ubuntu, and leaving it out - breaks virtual environments with a genuinely baffling error. + The `-venv` package is separate on Debian and Ubuntu, and leaving it out breaks virtual environments + with a genuinely baffling error. ## Pick an editor -No editor here is better than the others — more features is not the same as more -suitable. Pick one that fits what you're doing now and change later if it starts -getting in the way. +No editor here is better than the others — more features is not the same as more suitable. Pick one +that fits what you're doing now and change later if it starts getting in the way. === "Barely any setup" @@ -89,8 +87,7 @@ getting in the way. === "Full IDE" - Refactoring, debugging and project tooling built in. Heavier to start, worth - it on anything large. + Refactoring, debugging and project tooling built in. Heavier to start, worth it on anything large. | Editor | Notes | |--------|-------| @@ -100,14 +97,14 @@ getting in the way. !!! tip "Don't shop for long" - An hour comparing editors is an hour not spent writing Python. Take VS Code - if you have no opinion yet. + An hour comparing editors is an hour not spent writing Python. Take VS Code if you have no opinion + yet. ## Virtual environments -A virtual environment is a per-project copy of Python's package directory. -Without one, every project shares one set of packages, and two projects that need -different versions of the same library can't both work. +A virtual environment is a per-project copy of Python's package directory. Without one, every +project shares one set of packages, and two projects that need different versions of the same +library can't both work. === "venv (built in)" @@ -118,13 +115,13 @@ different versions of the same library can't both work. (.venv) $ pip install requests ``` - The `(.venv)` prefix means it's active. If it isn't there, `pip install` is - installing somewhere you didn't intend. + The `(.venv)` prefix means it's active. If it isn't there, `pip install` is installing somewhere you + didn't intend. === "uv (faster)" - [uv](https://docs.astral.sh/uv/) replaces `pip` and `venv` with one much - faster tool, and it manages Python versions too: + [uv](https://docs.astral.sh/uv/) replaces `pip` and `venv` with one much faster tool, and it manages + Python versions too: ```console $ uv init myproject @@ -133,17 +130,16 @@ different versions of the same library can't both work. $ uv run main.py ``` - `uv run` activates the environment for you, so there's nothing to forget. - Our own projects use it — see [Eos](../projects/our-projects/eos.md). + `uv run` activates the environment for you, so there's nothing to forget. Our own projects use it — + see [Eos](../projects/our-projects/eos.md). !!! tip "Add .venv to .gitignore" - A virtual environment is build output. It's large, it's platform-specific, - and committing it will earn you comments on your first pull request. + A virtual environment is build output. It's large, it's platform-specific, and committing it will + earn you comments on your first pull request. ## Where to go next The [learning path](learning-path.md) has material sorted by level, and the -[cheat sheets and tools](cheat-sheets.md) page has the things worth keeping in a -browser tab. If you're already stuck on something, -[ask well](asking-good-questions.md) and you'll get an answer. +[cheat sheets and tools](cheat-sheets.md) page has the things worth keeping in a browser tab. If +you're already stuck on something, [ask well](asking-good-questions.md) and you'll get an answer. diff --git a/docs/resources/index.md b/docs/resources/index.md index 24a9621..37f79b9 100644 --- a/docs/resources/index.md +++ b/docs/resources/index.md @@ -4,8 +4,8 @@ description: Curated Python learning material, vetted by people who answer quest # Resources -Material we recommend often enough to write down. Everything here has been read -by someone in the community who then said it was worth your time. +Material we recommend often enough to write down. Everything here has been read by someone in the +community who then said it was worth your time.
@@ -49,13 +49,13 @@ by someone in the community who then said it was worth your time. ## Suggesting a resource -Open a pull request against this site. Say what the resource is, who it's for, -and why you're recommending it over the obvious alternative. +Open a pull request against this site. Say what the resource is, who it's for, and why you're +recommending it over the obvious alternative. -We reject more suggestions than we accept, usually because the list is already -long enough at that level. Nothing personal. +We reject more suggestions than we accept, usually because the list is already long enough at that +level. Nothing personal. !!! note "No affiliate links" - Recommendations here are unpaid. If you have a financial interest in - something you're suggesting, say so in the pull request. + Recommendations here are unpaid. If you have a financial interest in something you're suggesting, + say so in the pull request. diff --git a/docs/resources/learning-path.md b/docs/resources/learning-path.md index e7a1861..a6495d2 100644 --- a/docs/resources/learning-path.md +++ b/docs/resources/learning-path.md @@ -4,8 +4,8 @@ description: Books, courses and exercises sorted by level rather than by fame. # Learning path -Pick one thing from your level and finish it. Collecting resources is a -procrastination technique with excellent branding. +Pick one thing from your level and finish it. Collecting resources is a procrastination technique +with excellent branding. ## Complete beginner @@ -24,19 +24,17 @@ You've never written code, or you've written a little and it didn't stick. Don't copy-paste them. The typos you make while typing are the lesson. -If you'd rather see the whole route before you start, -[roadmap.sh/python](https://roadmap.sh/python) lays the topics out as a map. Read -it once for orientation, then close it — the map isn't the walk. +If you'd rather see the whole route before you start, [roadmap.sh/python](https://roadmap.sh/python) +lays the topics out as a map. Read it once for orientation, then close it — the map isn't the walk. ### An hour of video first -Not a substitute for a course, but a decent way to find out whether the syntax -scares you. +Not a substitute for a course, but a decent way to find out whether the syntax scares you. -- [Python in one hour](https://www.youtube.com/watch?v=8KCuHHeC_M0) — current, - and a reasonable tour of the basics. -- [An older one-hour crash course](https://www.youtube.com/watch?v=kqtD5dpn9C8) - — some details have dated, the concepts haven't. +- [Python in one hour](https://www.youtube.com/watch?v=8KCuHHeC_M0) — current, and a reasonable tour + of the basics. +- [An older one-hour crash course](https://www.youtube.com/watch?v=kqtD5dpn9C8) — some details have + dated, the concepts haven't. ## Getting comfortable @@ -51,9 +49,9 @@ You can write a script. You're unsure whether you're writing it well. !!! note "Paid courses, without paying" - [Courson](https://courson.xyz/) collects 100%-off vouchers for Udemy - courses. The vouchers expire quickly and the quality varies as much as Udemy - does, so check the reviews before you spend an evening on one. + [Courson](https://courson.xyz/) collects 100%-off vouchers for Udemy courses. The vouchers expire + quickly and the quality varies as much as Udemy does, so check the reviews before you spend an + evening on one. ## Building things @@ -66,9 +64,9 @@ You can build something that works. You want it to be good. ## Practice between sessions -Short problems keep the syntax in your fingers on the days you don't have an -evening to spend. They're a supplement to building things, not a replacement — -nobody ever shipped anything by grinding exercises. +Short problems keep the syntax in your fingers on the days you don't have an evening to spend. +They're a supplement to building things, not a replacement — nobody ever shipped anything by +grinding exercises. | Site | Shape | Notes | |------|-------|-------| @@ -80,31 +78,30 @@ nobody ever shipped anything by grinding exercises. !!! tip "Read someone else's answer afterwards" - Solve it yourself first, then look. The gap between your version and a good - one is the part worth studying. + Solve it yourself first, then look. The gap between your version and a good one is the part worth + studying. ## Reference -Worth bookmarking rather than reading start to finish. There's more of this on -the [cheat sheets and tools](cheat-sheets.md) page. +Worth bookmarking rather than reading start to finish. There's more of this on the +[cheat sheets and tools](cheat-sheets.md) page. -- [The standard library index](https://docs.python.org/3/library/) — read this - before installing a dependency. The answer is often already installed. -- [PEP 8](https://peps.python.org/pep-0008/) — the style guide. Most of it is - handled by a formatter now. -- [PEP 20](https://peps.python.org/pep-0020/) — the Zen of Python. Quoted more - often than it's followed. +- [The standard library index](https://docs.python.org/3/library/) — read this before installing a + dependency. The answer is often already installed. +- [PEP 8](https://peps.python.org/pep-0008/) — the style guide. Most of it is handled by a formatter + now. +- [PEP 20](https://peps.python.org/pep-0020/) — the Zen of Python. Quoted more often than it's + followed. ## What we don't recommend -Tutorials older than about five years, unless they're teaching something that -hasn't changed. Python 2 material, obviously. Anything promising fluency in a -weekend. +Tutorials older than about five years, unless they're teaching something that hasn't changed. Python +2 material, obviously. Anything promising fluency in a weekend. -Video playlists that never build anything are also a trap — you'll feel -productive and retain very little. If a course has no exercises, add your own. +Video playlists that never build anything are also a trap — you'll feel productive and retain very +little. If a course has no exercises, add your own. !!! question "Stuck choosing?" - Ask in the help channels and say what you've already tried. Someone will - have an opinion, and probably a better one than this page. + Ask in the help channels and say what you've already tried. Someone will have an opinion, and + probably a better one than this page. diff --git a/docs/rules/channels.md b/docs/rules/channels.md index b0855ec..bda8f80 100644 --- a/docs/rules/channels.md +++ b/docs/rules/channels.md @@ -4,9 +4,8 @@ description: Which channel your message belongs in. # Channels -Post in the right place and you'll get an answer faster. Post in the wrong place -and maybe someone will move you, or your question won't get seen. - +Post in the right place and you'll get an answer faster. Post in the wrong place and maybe someone +will move you, or your question won't get seen. ## Getting help @@ -21,24 +20,22 @@ half-answers and an irritated moderator. ## Everything else -| Channel type | For | -|--------------|-----| -| General chat | Anything not a support request | -| Off-topic | Not Python. Still covered by [the rules](index.md) | -| Voice | Pair programming, study sessions, quiet co-working | +| Channel type | For | +|--------------|----------------------------------------------------| +| General chat | Anything not a support request | +| Off-topic | Not Python. Still covered by [the rules](index.md) | +| Voice | Pair programming, study sessions, quiet co-working | ## Threads -Use a thread when a conversation outlives its usefulness to the channel — a long -debugging session, a tangent, a design argument. Start one, don't apologise for -it. +Use a thread when a conversation outlives its usefulness to the channel — a long debugging session, +a tangent, a design argument. Start one, don't apologise for it. Threads inherit the rules of their parent channel. ## Bot commands -Commands work in most channels, but check before filling a help channel with bot -output. +Commands work in most channels, but check before filling a help channel with bot output. === "Slash commands" @@ -55,7 +52,6 @@ output. The full list, with permissions and arguments, is in the [Eos documentation](../projects/our-projects/eos.md). - === "Run code in the chat!" `>run` executes a Python code-block and replies with the output. @@ -64,7 +60,4 @@ output. ````text >run - ```py - print("oh wow!") - ``` - ```` + ```py print("oh wow!") ``` ```` diff --git a/docs/rules/code-of-conduct.md b/docs/rules/code-of-conduct.md index d7c1562..3ff6073 100644 --- a/docs/rules/code-of-conduct.md +++ b/docs/rules/code-of-conduct.md @@ -4,8 +4,8 @@ description: What counts as harassment here, and what staff do about it. # Code of conduct -[Rule 1](index.md#1-be-kind-and-respectful) says be kind and respectful. This -page explains what that means and what staff do about it. +[Rule 1](index.md#1-be-kind-and-respectful) says be kind and respectful. This page explains what +that means and what staff do about it. ## Expected behaviour @@ -16,37 +16,34 @@ page explains what that means and what staff do about it. ## Unacceptable behaviour -The following gets you removed, and the [moderation ladder](moderation.md#the-ladder) doesn't necessarily apply: +The following gets you removed, and the [moderation ladder](moderation.md#the-ladder) doesn't +necessarily apply: -- Slurs or harassment based on race, sex, gender, sexuality, disability, religion - or nationality. +- Slurs or harassment based on race, sex, gender, sexuality, disability, religion or nationality. - Sexual attention or content directed at a member, including in DMs. - Threats, stalking, or posting someone's personal information. - Sustained disruption after being asked to stop. !!! danger "Minors" - Discord's terms require members to be 13 or older, and older still in some - countries. Any sexual conduct directed at someone who is or appears to be a - minor results in an immediate ban and a report to Discord's Trust & Safety - team. There is no appeal. + Discord's terms require members to be 13 or older, and older still in some countries. Any sexual + conduct directed at someone who is or appears to be a minor results in an immediate ban and a report + to Discord's Trust & Safety team. There is no appeal. ## Grey areas -Some things aren't in either list. Heated technical arguments, sarcasm and -swearing are all normal here. The line is whether a reasonable person would read -it as aimed at humiliating someone. +Some things aren't in either list. Heated technical arguments, sarcasm and swearing are all normal +here. The line is whether a reasonable person would read it as aimed at humiliating someone. -If you're not sure whether something crosses the line, it probably does, and -asking a moderator first costs nothing. +If you're not sure whether something crosses the line, it probably does, and asking a moderator +first costs nothing. ## Enforcement -Reports go to staff, who decide together where possible. A moderator involved in -the incident doesn't rule on it unless nobody else is around. +Reports go to staff, who decide together where possible. A moderator involved in the incident +doesn't rule on it unless nobody else is around. -Staff will tell you what rule you broke and what happens next. They won't share -who reported you. +Staff will tell you what rule you broke and what happens next. They won't share who reported you. ## Staff have the final say diff --git a/docs/rules/index.md b/docs/rules/index.md index fb05be6..61a37f5 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -18,90 +18,85 @@ Seven rules. Read them once and you'll be fine. ## 1. Be kind and respectful -Treat others the way you'd like to be treated. No mean-spirited comments or -behaviour — keep conversations positive and constructive. +Treat others the way you'd like to be treated. No mean-spirited comments or behaviour — keep +conversations positive and constructive. -Disagree as much as you like, but direct it at the code, the approach or the -claim, never at the person holding it. Condescension counts, and "just being -blunt" isn't a defence. +Disagree as much as you like, but direct it at the code, the approach or the claim, never at the +person holding it. Condescension counts, and "just being blunt" isn't a defense. Harassment, slurs and bigotry get you removed without a warning ladder. See [Code of conduct](code-of-conduct.md) for what that covers. ## 2. Stay on topic -Stick to the subject of the channel you're posting in. If your question doesn't -fit anywhere obvious, ask anyway — we'd rather help you find your way then you not ask because you didn't know where to ask. +Stick to the subject of the channel you're posting in. If your question doesn't fit anywhere +obvious, ask anyway — we'd rather help you find your way then you not ask because you didn't know +where to ask. [Channels](channels.md) says what goes where. ## 3. Share responsibly -No self-promotion or unsolicited ads. Sharing a personal project is welcome and -encouraged, as long as you aren't looking to sign people up for something. +No self-promotion or unsolicited ads. Sharing a personal project is welcome and encouraged, as long +as you aren't looking to sign people up for something. When you share something you built: - **Always include the source code.** A repository, a gist, or a fenced block. -- **Never post an `.exe`**, or any other compiled binary. Nobody can read it, - and nobody should run it. Ever. +- **Never post an `.exe`**, or any other compiled binary. Nobody can read it, and nobody should run + it. Ever. -Got something you genuinely need to advertise? Ask a moderator first through the -**/ticket** system. If your heart is pure, and your intentions are good, we will probably let you do it! +Got something you genuinely need to advertise? Ask a moderator first through the **/ticket** system. +If your heart is pure, and your intentions are good, we will probably let you do it! !!! tip "Nobody from staff will DM you first" - Staff open a thread or use the ticket system. A DM claiming to be staff and - asking you for anything is a scam. Report it. + Staff open a thread or use the ticket system. A DM claiming to be staff and asking you for anything + is a scam. Report it. ## 4. Ethical coding only -Learning and exploring are the point of this server. Hacking and other unethical -practices are not. +Learning and exploring are the point of this server. Hacking and other unethical practices are not. -White hat work is welcome as long as you're transparent about what you're doing -and why. If you can't say who authorised it, don't ask about it here. +White hat work is welcome as long as you're transparent about what you're doing and why. If you +can't say who authorised it, don't ask about it here. ## 5. Moderators have final say -If you have a concern or a dispute, the moderators have the final word. They work -hard to keep this place safe and enjoyable, so trust their judgement — they're -here to help. +If you have a concern or a dispute, the moderators have the final word. They work hard to keep this +place safe and enjoyable, so trust their judgement — they're here to help. Arguing a decision in public channels after it's been made is itself a problem. [Moderation](moderation.md) explains how to appeal properly. ## 6. No jobs or employment advertising -Discord isn't where you'll find work — use a real job board. Job posts and -recruitment pitches get deleted, and you'll be warned or banned depending on how -we feel about it. See rule 5. +Discord isn't where you'll find work — use a real job board. Job posts and recruitment pitches get +deleted, and you'll be warned or banned depending on how we feel about it. See rule 5. ## 7. Ask effective questions When you want help, give people something to work with: - Describe the problem clearly and concisely. -- Include the relevant code, the full error message, and screenshots where they - actually add something. +- Include the relevant code, the full error message, and screenshots where they actually add + something. - Say what you've already tried and what you're trying to achieve. - Be patient and open to guidance. We're here to help you grow. -Paste code as text in a fenced block — not a screenshot of it, not a photo of -your monitor. Helpers need to copy and run your code, and they can't copy a JPEG. +Paste code as text in a fenced block — not a screenshot of it, not a photo of your monitor. Helpers +need to copy and run your code, and they can't copy a JPEG. -[Asking good questions](../resources/asking-good-questions.md) covers this in -detail, with examples. +[Asking good questions](../resources/asking-good-questions.md) covers this in detail, with examples. ## Reporting something -Use the **/ticket** system. It reaches the moderators without putting the -incident in a public channel. +Use the **/ticket** system. It reaches the moderators without putting the incident in a public +channel. -Ping staff directly when something needs a moderator *now* — a raid, a scam, or -someone in crisis. +Ping staff directly when something needs a moderator *now* — a raid, a scam, or someone in crisis. ## What happens if you break a rule -[Moderation](moderation.md) sets out the enforcement ladder, what the bot does -automatically, and how to appeal. +[Moderation](moderation.md) sets out the enforcement ladder, what the bot does automatically, and +how to appeal. diff --git a/docs/rules/moderation.md b/docs/rules/moderation.md index 67d5239..8d7647d 100644 --- a/docs/rules/moderation.md +++ b/docs/rules/moderation.md @@ -8,14 +8,14 @@ What happens when a rule gets broken ## The ladder -| Step | Action | Typically triggered by | -|------|--------|------------------------| -| 1 | Informal nudge in channel | First minor slip, you'll get notified | -| 2 | Formal warning, logged | Repeat of the same slip, or ignoring a moderator | -| 3 | Timeout, minutes to hours | Heated argument or overexcitment that won't cool down | -| 4 | Quarantine | Spam, suspected compromised account. Step into our office. | -| 5 | Kick | Pattern of warnings with no change | -| 6 | Ban | Code of conduct breach, scams, ban evasion | +| Step | Action | Typically triggered by | +|------|---------------------------|------------------------------------------------------------| +| 1 | Informal nudge in channel | First minor slip, you'll get notified | +| 2 | Formal warning, logged | Repeat of the same slip, or ignoring a moderator | +| 3 | Timeout, minutes to hours | Heated argument or overexcitment that won't cool down | +| 4 | Quarantine | Spam, suspected compromised account. Step into our office. | +| 5 | Kick | Pattern of warnings with no change | +| 6 | Ban | Code of conduct breach, scams, ban evasion | Steps aren't mandatory stops, and moderators get the final say. @@ -23,23 +23,22 @@ Steps aren't mandatory stops, and moderators get the final say. Some of this is handled by the bot, with no moderator involved. -| Behaviour | Trigger | Action | -|-----------|---------|--------| -| Spam detection | Same message sent 3 or more times | Warns at 3, quarantines at 4, deletes the messages | -| Verification | Joining the server | You must confirm you're not a robot to get the verified role | -| Points | Sending or deleting a message | Adjusts your score — see [the leaderboard](../projects/our-projects/eos.md#points) | +| Behaviour | Trigger | Action | +|----------------|-----------------------------------|------------------------------------------------------------------------------------| +| Spam detection | Same message sent 3 or more times | Warns at 3, quarantines at 4, deletes the messages | +| Verification | Joining the server | You must confirm you're not a robot to get the verified role | +| Points | Sending or deleting a message | Adjusts your score — see [the leaderboard](../projects/our-projects/eos.md#points) | !!! info "Quarantine isn't a ban" - Quarantine removes your verified role and hides the server's channels. It's - what happens when the bot or a mod thinks your account is compromised, spamming or annoying. - A moderator can release you in seconds once it's sorted. + Quarantine removes your verified role and hides the server's channels. It's what happens when the + bot or a mod thinks your account is compromised, spamming or annoying. A moderator can release you + in seconds once it's sorted. ## What moderators can see -Message edits and deletions are logged to a staff-only channel, along with name -changes, avatar changes, role changes, and joins and leaves. Your deleted -messages are already logged. +Message edits and deletions are logged to a staff-only channel, along with name changes, avatar +changes, role changes, and joins and leaves. Your deleted messages are already logged. Staff cannot read your DMs with other members. @@ -47,14 +46,13 @@ Staff cannot read your DMs with other members. === "Timeout or warning" - Wait for it to expire, then take it up with the moderator who issued it. If - you think they got it wrong, ask another moderator to review. + Wait for it to expire, then take it up with the moderator who issued it. If you think they got it + wrong, ask another moderator to review. === "Kick" - Rejoin with the invite. A kick isn't a ban — it's a firm request to reset - your behaviour. Come back and pick up where you left off, minus the - behaviour. + Rejoin with the invite. A kick isn't a ban — it's a firm request to reset your behaviour. Come back + and pick up where you left off, minus the behaviour. === "Ban"