hoodscript 1.1.0__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. {hoodscript-1.1.0 → hoodscript-1.3.0}/CHANGELOG.md +106 -0
  2. {hoodscript-1.1.0 → hoodscript-1.3.0}/CONTRIBUTING.md +19 -0
  3. {hoodscript-1.1.0 → hoodscript-1.3.0}/PKG-INFO +34 -1
  4. {hoodscript-1.1.0 → hoodscript-1.3.0}/README.md +21 -0
  5. {hoodscript-1.1.0 → hoodscript-1.3.0}/SECURITY.md +4 -2
  6. hoodscript-1.3.0/docs/adr/0004-no-regional-dialect-overlays.md +45 -0
  7. hoodscript-1.3.0/docs/grammar.ebnf +59 -0
  8. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/onboarding.md +30 -2
  9. hoodscript-1.3.0/examples/quickstart.ipynb +142 -0
  10. hoodscript-1.3.0/examples/solutions/beatlab/stage1.hs +10 -0
  11. hoodscript-1.3.0/examples/solutions/beatlab/stage2.hs +15 -0
  12. hoodscript-1.3.0/examples/solutions/beatlab/stage3.hs +11 -0
  13. hoodscript-1.3.0/examples/solutions/beatlab/stage4.hs +14 -0
  14. hoodscript-1.3.0/examples/solutions/beatlab/stage5.hs +13 -0
  15. hoodscript-1.3.0/examples/solutions/cookout/stage1.hs +9 -0
  16. hoodscript-1.3.0/examples/solutions/cookout/stage2.hs +8 -0
  17. hoodscript-1.3.0/examples/solutions/cookout/stage3.hs +5 -0
  18. hoodscript-1.3.0/examples/solutions/cookout/stage4.hs +26 -0
  19. hoodscript-1.3.0/examples/solutions/cookout/stage5.hs +13 -0
  20. hoodscript-1.3.0/examples/solutions/dropday/stage1.hs +13 -0
  21. hoodscript-1.3.0/examples/solutions/dropday/stage2.hs +14 -0
  22. hoodscript-1.3.0/examples/solutions/dropday/stage3.hs +12 -0
  23. hoodscript-1.3.0/examples/solutions/dropday/stage4.hs +11 -0
  24. hoodscript-1.3.0/examples/solutions/dropday/stage5.hs +16 -0
  25. hoodscript-1.3.0/examples/solutions/level1.hs +9 -0
  26. hoodscript-1.3.0/examples/solutions/level2.hs +9 -0
  27. hoodscript-1.3.0/examples/solutions/level3.hs +14 -0
  28. hoodscript-1.3.0/examples/solutions/level4.hs +18 -0
  29. hoodscript-1.3.0/examples/solutions/level5.hs +38 -0
  30. hoodscript-1.3.0/examples/solutions/level6.hs +14 -0
  31. hoodscript-1.3.0/examples/solutions/level7.hs +37 -0
  32. hoodscript-1.3.0/examples/solutions/level8.hs +41 -0
  33. {hoodscript-1.1.0 → hoodscript-1.3.0}/pyproject.toml +13 -2
  34. hoodscript-1.3.0/scripts/gen_ebnf.py +33 -0
  35. hoodscript-1.3.0/scripts/hooks/pre-push +11 -0
  36. hoodscript-1.3.0/scripts/install-hooks.sh +7 -0
  37. hoodscript-1.3.0/src/hoodarcade/__init__.py +9 -0
  38. hoodscript-1.3.0/src/hoodarcade/cli.py +344 -0
  39. hoodscript-1.3.0/src/hoodarcade/core/runtime.py +148 -0
  40. hoodscript-1.3.0/src/hoodarcade/core/ui.py +232 -0
  41. hoodscript-1.3.0/src/hoodarcade/games/beatlab.py +393 -0
  42. hoodscript-1.3.0/src/hoodarcade/games/cookout.py +446 -0
  43. hoodscript-1.3.0/src/hoodarcade/games/dropday.py +415 -0
  44. hoodscript-1.3.0/src/hoodfarm/__init__.py +3 -0
  45. hoodscript-1.3.0/src/hoodfarm/cli.py +249 -0
  46. hoodscript-1.3.0/src/hoodfarm/drone.py +158 -0
  47. hoodscript-1.3.0/src/hoodfarm/grid.py +216 -0
  48. hoodscript-1.3.0/src/hoodfarm/levels.py +402 -0
  49. hoodscript-1.3.0/src/hoodfarm/renderer.py +249 -0
  50. hoodscript-1.3.0/src/hoodfarm/runner.py +224 -0
  51. hoodscript-1.3.0/src/hoodlib/__init__.py +9 -0
  52. hoodscript-1.3.0/src/hoodlib/disk.py +177 -0
  53. hoodscript-1.3.0/src/hoodscript/__init__.py +16 -0
  54. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/_version.py +2 -2
  55. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/cli.py +60 -1
  56. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/errors/translator.py +4 -1
  57. hoodscript-1.3.0/src/hoodscript/kernel/__init__.py +12 -0
  58. hoodscript-1.3.0/src/hoodscript/kernel/__main__.py +13 -0
  59. hoodscript-1.3.0/src/hoodscript/kernel/installer.py +54 -0
  60. hoodscript-1.3.0/src/hoodscript/kernel/kernel.py +292 -0
  61. hoodscript-1.3.0/src/hoodscript/kernel/magics.py +104 -0
  62. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/patterns.py +21 -11
  63. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/traceback_handler.py +1 -1
  64. hoodscript-1.3.0/src/hoodscript/zen.py +60 -0
  65. hoodscript-1.3.0/src/vibe.py +8 -0
  66. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/test_exec_sites.py +1 -1
  67. hoodscript-1.3.0/tests/test_arcade.py +224 -0
  68. hoodscript-1.3.0/tests/test_arcade_gates.py +72 -0
  69. hoodscript-1.3.0/tests/test_fuzz_ebnf.py +178 -0
  70. hoodscript-1.3.0/tests/test_game_engine.py +249 -0
  71. hoodscript-1.3.0/tests/test_grammar_ebnf.py +19 -0
  72. hoodscript-1.3.0/tests/test_hoodlib_disk.py +101 -0
  73. hoodscript-1.3.0/tests/test_kernel.py +159 -0
  74. hoodscript-1.3.0/tests/test_kernel_zmq.py +88 -0
  75. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_patterns.py +13 -0
  76. hoodscript-1.1.0/src/hoodscript/__init__.py +0 -9
  77. {hoodscript-1.1.0 → hoodscript-1.3.0}/.gitignore +0 -0
  78. {hoodscript-1.1.0 → hoodscript-1.3.0}/CODE_OF_CONDUCT.md +0 -0
  79. {hoodscript-1.1.0 → hoodscript-1.3.0}/LICENSE +0 -0
  80. {hoodscript-1.1.0 → hoodscript-1.3.0}/SPRINT_PLAN.md +0 -0
  81. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/adr/0001-token-pipeline-over-parser.md +0 -0
  82. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/adr/0002-keyword-reconciliation.md +0 -0
  83. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/adr/0003-inclusive-ranges.md +0 -0
  84. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/adr/README.md +0 -0
  85. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/archive/HOODSCRIPT_COMPLETE_MASTER_SYSTEM.md +0 -0
  86. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/archive/HOODSCRIPT_FULL_ENGINEERING_SUITE.md +0 -0
  87. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/archive/HOODSCRIPT_UNSPRED_FEATURES_ROADMAP.md +0 -0
  88. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/curriculum.md +0 -0
  89. {hoodscript-1.1.0 → hoodscript-1.3.0}/docs/keywords.md +0 -0
  90. {hoodscript-1.1.0 → hoodscript-1.3.0}/out.txt +0 -0
  91. {hoodscript-1.1.0 → hoodscript-1.3.0}/playground/app.js +0 -0
  92. {hoodscript-1.1.0 → hoodscript-1.3.0}/playground/bundle.js +0 -0
  93. {hoodscript-1.1.0 → hoodscript-1.3.0}/playground/examples.js +0 -0
  94. {hoodscript-1.1.0 → hoodscript-1.3.0}/playground/hoodscript-latest-py3-none-any.whl +0 -0
  95. {hoodscript-1.1.0 → hoodscript-1.3.0}/playground/index.html +0 -0
  96. {hoodscript-1.1.0 → hoodscript-1.3.0}/playground/style.css +0 -0
  97. {hoodscript-1.1.0 → hoodscript-1.3.0}/playground/worker.js +0 -0
  98. {hoodscript-1.1.0 → hoodscript-1.3.0}/scripts/build_playground.py +0 -0
  99. {hoodscript-1.1.0 → hoodscript-1.3.0}/scripts/gen_keywords.py +0 -0
  100. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/__main__.py +0 -0
  101. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/cache.py +0 -0
  102. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/constants.py +0 -0
  103. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/debugger.py +0 -0
  104. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/errors/__init__.py +0 -0
  105. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/errors/catalog.py +0 -0
  106. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/errors/renderer.py +0 -0
  107. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/formatter.py +0 -0
  108. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/importer.py +0 -0
  109. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/linter.py +0 -0
  110. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/lsp.py +0 -0
  111. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/migrator.py +0 -0
  112. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/repl.py +0 -0
  113. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/sandbox.py +0 -0
  114. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/stubs.py +0 -0
  115. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/transpiler.py +0 -0
  116. {hoodscript-1.1.0 → hoodscript-1.3.0}/src/hoodscript/tutor.py +0 -0
  117. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/conftest.py +0 -0
  118. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/deep_nesting.hs +0 -0
  119. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/fork_bomb.hs +0 -0
  120. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/huge_literal.hs +0 -0
  121. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/import_escapes.hs +0 -0
  122. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/infinite_recursion.hs +0 -0
  123. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/open_file.hs +0 -0
  124. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/pathological_indent.hs +0 -0
  125. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/runaway_output.hs +0 -0
  126. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/corpus/runaway_time.hs +0 -0
  127. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/test_corpus.py +0 -0
  128. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/test_fuzz.py +0 -0
  129. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/security/test_sandbox.py +0 -0
  130. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_cli.py +0 -0
  131. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_conformance.py +0 -0
  132. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_debugger.py +0 -0
  133. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_docs.py +0 -0
  134. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_errors.py +0 -0
  135. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_fmt.py +0 -0
  136. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_grammar_canonical.py +0 -0
  137. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_importer.py +0 -0
  138. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_keywords_doc.py +0 -0
  139. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_learn.py +0 -0
  140. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_lint.py +0 -0
  141. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_lsp_features.py +0 -0
  142. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_playground.py +0 -0
  143. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_release.py +0 -0
  144. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_repl.py +0 -0
  145. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_transpiler.py +0 -0
  146. {hoodscript-1.1.0 → hoodscript-1.3.0}/tests/test_vscode_extension.py +0 -0
@@ -3,6 +3,111 @@
3
3
  All notable changes to HoodScript. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
4
  Versioning: the keyword set is the public API; changing it is at least a minor bump.
5
5
 
6
+ ## [Unreleased]
7
+
8
+ ## [1.3.0] — 2026-09-12
9
+
10
+ Three features that were on `main` but not on PyPI: the two games and the
11
+ ecosystem sprint. Keyword set unchanged (v1.1); minor bump for the new
12
+ packages and CLI commands.
13
+
14
+ ### Added
15
+
16
+ - `hoodarcade levels [game]`: the stage table for one game (`list` stays the
17
+ all-games form). Added while aligning a stale "Arcade + Ecosystem" prompt
18
+ with the release — the reconciliation is `PROMPTS.md` §3.5.
19
+
20
+ - **The Drone Was Replaced** (`hoodfarm`, `pip install "hoodscript[farm]"`, also
21
+ `hoodscript farm …`): a terminal grid-automation game in the style of *The
22
+ Farmer Was Replaced*. Program a drone (`bot.move/harvest/plant/water/till/
23
+ inspect_ground/measure_water`, `bot.bag/energy/ticks_used`) in HoodScript
24
+ across 8 levels (single-tile harvest → loops → 2D traversal → conditional
25
+ weeding → irrigation → inventory quotas → companion planting → an
26
+ energy-budgeted supply chain). Rich TUI with emoji tiles, telemetry,
27
+ inventory ledger and log console (ASCII fallback); `hoodfarm play <level>`
28
+ hot-reloads `solution.hs` on save; `hoodfarm run --benchmark` and
29
+ `hoodfarm test` run headless with proper exit codes. Deterministic ticks.
30
+ Reference solutions for all 8 levels in `examples/solutions/`.
31
+ - QA on acceptance (external batch): it shipped with a **private game lexicon**
32
+ — `cook`/`serve`/`run_thru`/`Facts` (cut under Rule Zero) and `dip`
33
+ remapped to `break` — so 7 of 8 solutions did not parse under `hoodscript`
34
+ and the game taught a different language. Removed; every starter template
35
+ and solution translated to v1.1 and verified to win through the real
36
+ transpiler. Crashes now go through the JPE engine with the player's line and
37
+ the game state ("drone at (2, 4), energy 0, tick 50"). Cut builtin aliases
38
+ injected as globals (`span`, `lineup`, `ledger`, `count_up`) removed.
39
+ Tests guard all of it (no cut word as a code token anywhere in the game).
40
+
41
+ - **HoodArcade** (`hoodarcade`, `pip install "hoodscript[arcade]"`, also
42
+ `hoodscript arcade …`): three terminal games, five stages each, with Rich
43
+ viewports (grill rack + Spades table, 16-step 808 matrix, SNKRS drop feed),
44
+ hot-reload on save, and progress in `~/.hoodarcade/progress.json`:
45
+ *Big Mama's Cookout* (grill timing, the potato-salad exception test, aux-cord
46
+ sorting, a Spades rule engine, an autonomous Spades partner), *BeatLab 808*
47
+ (four-on-the-floor, trap-hat triplets by modulo, sample chopping, 808 glide
48
+ interpolation, a full arrangement), *Drop Day* (stock monitor, legit-check
49
+ filter, exponential backoff with `tryna`/`catch`, multi-cart, a circular
50
+ trade-graph search). Reference solutions for all 15 stages.
51
+ - QA on acceptance (external batch): same defect as the farm — a **private
52
+ lexicon** (`cook`/`serve`/`run_thru`/`Facts`, `dip`→`break`) meant no stage
53
+ solution ran under `hoodscript`; removed, everything translated to v1.1.
54
+ **Every "starter" template was the finished solution** — a player opened a
55
+ stage already solved; all 15 rewritten as real scaffolds (API shown,
56
+ algorithm left to the player; tests assert scaffolds fail and solutions
57
+ pass). Crashes in player code, including ones the stage checkers catch, now
58
+ surface as JPE reports with the failing line; a checker fed the wrong
59
+ return type fails the stage in plain English instead of raising.
60
+
61
+ - **HPEP 20 — The Zen of HoodScript.** `hoodscript zen` (add `--notes` to see
62
+ which file each line points at) and `import vibe` from any program, like
63
+ `import this`. Nineteen lines, each a decision this repo actually made.
64
+ - **`docs/grammar.ebnf`** — the formal grammar as its own artifact, generated
65
+ from `GRAMMAR.md` by `scripts/gen_ebnf.py`; a test fails if they drift and
66
+ another checks every keyword has a production (that found `ask` missing).
67
+ - **Grammar-directed fuzzing** (`tests/test_fuzz_ebnf.py`, Hypothesis): generates
68
+ valid programs from the grammar and asserts they transpile, compile, keep
69
+ their line count, contain no leaked sentinels or keywords, and that
70
+ `py2hood(transpile(p))` transpiles back to the same Python. Found and fixed
71
+ two pattern-layer bugs on its first run: `x = ask "name? "` was a syntax
72
+ error (R12 only fired at statement start; now anywhere), and `holla (x)` was
73
+ not reversible (whitespace now decides: `holla(x)` is a call, `holla (x)` is
74
+ the statement form). `HYPOTHESIS_PROFILE=thorough` runs 2,000 examples per
75
+ property.
76
+ - **`hoodlib.disk`** — atomic, thread-safe JSON/CSV read/write and backups,
77
+ standard library only (`from hoodlib import disk`). Errors are the Python
78
+ exceptions the crash reporter already explains.
79
+ - **ADR-0004: no regional dialect overlays.** A proposal for Bay Area / Atlanta
80
+ / DMV / MLE token overlays was declined under Rule Zero; a cited, single-
81
+ variety Tier B extension remains possible via the sourcing procedure. Two
82
+ companion proposals (`hoodpkg`/`hood.lock`, and a `hoodlib` with AES-GCM and
83
+ an async HTTP client) were dropped as duplicating Python and its packaging.
84
+
85
+ ## [1.2.0] — 2026-09-11
86
+
87
+ ### Added
88
+
89
+ - **Interactive Jupyter Notebook Kernel & IPython Magics** (`src/hoodscript/kernel/`, `examples/quickstart.ipynb`):
90
+ - Dedicated standalone Jupyter kernel (`hoodscript-kernel` / `HoodScriptKernel`) subclassing `ipykernel.kernelbase.Kernel`.
91
+ - Automatic 1:1 transpilation of notebook cells to Python prior to execution in the kernel's persistent namespace.
92
+ - Rich HTML plain-English JPE error cards rendered in-cell with collapsible raw Python tracebacks.
93
+ - Dynamic tab autocompletion over HoodScript keywords, patterns, exception names, and namespace variables.
94
+ - Cell and line inspection magics: `%hood_transpile` (preview generated Python without executing) and `%hood_tb` (toggle raw traceback view).
95
+ - IPython extension (`%load_ext hoodscript`) providing `%%hood` and `%%hood_transpile` for hybrid Python/HoodScript notebooks and Google Colab.
96
+ - CLI installer subcommand: `hoodscript kernel install [--user] [--prefix PREFIX]`.
97
+ - Interactive starter notebook: `examples/quickstart.ipynb`.
98
+ - Optional dependency extra: `pip install hoodscript[jupyter]`.
99
+ - QA (audited end to end over ZMQ with `jupyter_client` before acceptance; four
100
+ defects fixed): `holla` output never reached the cell (the base `Kernel`
101
+ never tells ipykernel's stdout stream which cell is running — `set_parent`
102
+ now does); a trailing bare expression displayed nothing (now shown as the
103
+ result, like IPython); crash cards showed the *Python* line (`def f()`) and,
104
+ for syntax errors, a stdlib `ast.py` frame (cells are registered in
105
+ `linecache` as `<notebook>`, a program pseudo-file; syntax errors carry no
106
+ frames); `%load_ext hoodscript` as documented did not work (only
107
+ `hoodscript.kernel` did) and `examples/quickstart.ipynb` had no kernelspec
108
+ metadata. `tests/test_kernel_zmq.py` drives the real kernel process.
109
+
110
+
6
111
  ## [1.1.0] — 2026-09-11
7
112
 
8
113
  The reconciled language. Every keyword is now either cited in
@@ -179,5 +284,6 @@ PEP 552 bytecode cache, CLI, REPL, crash reports with `*Trip` names,
179
284
  `py2hood` / `hood2py`, stub generator, pygls language server (diagnostics,
180
285
  hover, completion). Keyword set later found to be uncited — see v1.1.0.
181
286
 
287
+ [1.2.0]: https://github.com/khaoticdev62/hoodscript/compare/v1.1.0...v1.2.0
182
288
  [1.1.0]: https://github.com/khaoticdev62/hoodscript/compare/bf801ab...v1.1.0
183
289
  [1.0.0]: https://github.com/khaoticdev62/hoodscript/commits/bf801ab
@@ -64,6 +64,15 @@ Before every push:
64
64
  ruff check && pytest
65
65
  ```
66
66
 
67
+ Enforce it locally once per clone — the versioned pre-push hook runs exactly
68
+ this and refuses the push if it fails:
69
+
70
+ ```bash
71
+ ./scripts/install-hooks.sh
72
+ ```
73
+
74
+ (If you pipe `ruff check` into anything, you lose its exit code. Don't.)
75
+
67
76
  That is exactly what CI runs, on Ubuntu, macOS, and Windows × Python
68
77
  3.10–3.13, plus a CLI smoke test. Python's exception *messages* differ between
69
78
  versions (`was never closed` vs `EOF in multi-line statement`), so a catalog
@@ -107,6 +116,16 @@ with a gate. Commit at the gate with a message that says what changed and
107
116
  why; the changelog is written from those messages. Update `CLAUDE.md` when a
108
117
  decision changes — stale context is worse than none.
109
118
 
119
+ ## Landing changes
120
+
121
+ `main` is protected: the Ubuntu/macOS/Windows test legs and the build must be
122
+ green, force-pushes and deletions are refused, and pull requests need a
123
+ code-owner review (`.github/CODEOWNERS`). **Work you did not write yourself —
124
+ an agent's output included — lands as a pull request**, gets `/code-review`
125
+ and the end-to-end audit in [`PROMPTS.md`](PROMPTS.md) §2.8, and only then
126
+ merges. Two batches arrived on 2026-09-11 claiming completion with defects
127
+ their own tests could not see; that is why.
128
+
110
129
  ## Working with an AI agent
111
130
 
112
131
  Paste the standing brief from [`PROMPTS.md`](PROMPTS.md) §0 at the top of
@@ -1,21 +1,28 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: hoodscript
3
- Version: 1.1.0
3
+ Version: 1.3.0
4
4
  Summary: A production-grade Python 3 conlang based on AAVE with 1:1 AST parity.
5
5
  License: MIT
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.10
8
8
  Provides-Extra: all
9
+ Requires-Dist: ipykernel>=6.0.0; extra == 'all'
10
+ Requires-Dist: ipython>=8.0.0; extra == 'all'
9
11
  Requires-Dist: jedi>=0.19.1; extra == 'all'
10
12
  Requires-Dist: mypy>=1.9.0; extra == 'all'
11
13
  Requires-Dist: prompt-toolkit>=3.0.40; extra == 'all'
12
14
  Requires-Dist: pygls<2,>=1.3.1; extra == 'all'
13
15
  Requires-Dist: rich>=13.7; extra == 'all'
14
16
  Requires-Dist: ruff>=0.3.0; extra == 'all'
17
+ Provides-Extra: arcade
18
+ Requires-Dist: rich>=13.7; extra == 'arcade'
15
19
  Provides-Extra: dev
16
20
  Requires-Dist: build>=1.1.0; extra == 'dev'
17
21
  Requires-Dist: debugpy>=1.8.0; extra == 'dev'
18
22
  Requires-Dist: hatch-vcs>=0.4.0; extra == 'dev'
23
+ Requires-Dist: hypothesis>=6.100; extra == 'dev'
24
+ Requires-Dist: ipykernel>=6.0.0; extra == 'dev'
25
+ Requires-Dist: ipython>=8.0.0; extra == 'dev'
19
26
  Requires-Dist: jedi>=0.19.1; extra == 'dev'
20
27
  Requires-Dist: mypy>=1.9.0; extra == 'dev'
21
28
  Requires-Dist: prompt-toolkit>=3.0.40; extra == 'dev'
@@ -24,6 +31,11 @@ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
24
31
  Requires-Dist: pytest>=8.0.0; extra == 'dev'
25
32
  Requires-Dist: rich>=13.7; extra == 'dev'
26
33
  Requires-Dist: ruff>=0.3.0; extra == 'dev'
34
+ Provides-Extra: farm
35
+ Requires-Dist: rich>=13.7; extra == 'farm'
36
+ Provides-Extra: jupyter
37
+ Requires-Dist: ipykernel>=6.0.0; extra == 'jupyter'
38
+ Requires-Dist: ipython>=8.0.0; extra == 'jupyter'
27
39
  Provides-Extra: lsp
28
40
  Requires-Dist: jedi>=0.19.1; extra == 'lsp'
29
41
  Requires-Dist: pygls<2,>=1.3.1; extra == 'lsp'
@@ -96,9 +108,12 @@ with `PYTHONPATH=src` and use `python3 -m hoodscript` instead of `hoodscript`.
96
108
  hoodscript hello.hs # transpile + execute
97
109
  hoodscript -c hello.hs # print the Python it becomes
98
110
  hoodscript repl --mirror # interactive REPL (hood> prompt; chill to exit; --mirror shows the Python)
111
+ hoodscript playground # launch in-browser Pyodide WebAssembly playground
112
+ hoodscript kernel install # Jupyter kernel (pip install "hoodscript[jupyter]"); or %load_ext hoodscript
99
113
  hoodscript fmt|lint <file.hs> # formatter / linter (pip install "hoodscript[tools]")
100
114
  hoodscript learn [topic] # interactive tutor driving docs/curriculum.md
101
115
  hoodscript # a short tour of all commands
116
+ hoodscript zen # the Zen of HoodScript (HPEP 20); or `import vibe`
102
117
  hoodscript lsp # language server over stdio, for editors
103
118
  hoodscript make-stubs f.py # emit a .pyi-style stub with empty bodies
104
119
  ```
@@ -158,6 +173,24 @@ Everything else — `if`, `else`, `while`, `import`, `with`, `match`, `None`,
158
173
  `self`, every builtin — is Python's own word, and every Python keyword still
159
174
  works in a `.hs` file.
160
175
 
176
+ ## Play
177
+
178
+ ```bash
179
+ pip install "hoodscript[farm]"
180
+ hoodfarm levels # the 8 challenges
181
+ hoodfarm play 1 # edit solution.hs in your editor; the farm re-runs on every save
182
+ hoodfarm run my.hs -b # headless benchmark, exit 0 on pass
183
+ ```
184
+
185
+ *The Drone Was Replaced*: program a farming drone in HoodScript, one level at
186
+ a time. Same language, same crash reports — the game just adds a `bot`.
187
+
188
+ ```bash
189
+ pip install "hoodscript[arcade]"
190
+ hoodarcade # Big Mama's Cookout · BeatLab 808 · Drop Day
191
+ hoodarcade play cookout 1 # edit the solution file; the stage re-runs on save
192
+ ```
193
+
161
194
  ## Learn
162
195
 
163
196
  - [`docs/onboarding.md`](docs/onboarding.md) — from zero to a running program in ten minutes
@@ -58,9 +58,12 @@ with `PYTHONPATH=src` and use `python3 -m hoodscript` instead of `hoodscript`.
58
58
  hoodscript hello.hs # transpile + execute
59
59
  hoodscript -c hello.hs # print the Python it becomes
60
60
  hoodscript repl --mirror # interactive REPL (hood> prompt; chill to exit; --mirror shows the Python)
61
+ hoodscript playground # launch in-browser Pyodide WebAssembly playground
62
+ hoodscript kernel install # Jupyter kernel (pip install "hoodscript[jupyter]"); or %load_ext hoodscript
61
63
  hoodscript fmt|lint <file.hs> # formatter / linter (pip install "hoodscript[tools]")
62
64
  hoodscript learn [topic] # interactive tutor driving docs/curriculum.md
63
65
  hoodscript # a short tour of all commands
66
+ hoodscript zen # the Zen of HoodScript (HPEP 20); or `import vibe`
64
67
  hoodscript lsp # language server over stdio, for editors
65
68
  hoodscript make-stubs f.py # emit a .pyi-style stub with empty bodies
66
69
  ```
@@ -120,6 +123,24 @@ Everything else — `if`, `else`, `while`, `import`, `with`, `match`, `None`,
120
123
  `self`, every builtin — is Python's own word, and every Python keyword still
121
124
  works in a `.hs` file.
122
125
 
126
+ ## Play
127
+
128
+ ```bash
129
+ pip install "hoodscript[farm]"
130
+ hoodfarm levels # the 8 challenges
131
+ hoodfarm play 1 # edit solution.hs in your editor; the farm re-runs on every save
132
+ hoodfarm run my.hs -b # headless benchmark, exit 0 on pass
133
+ ```
134
+
135
+ *The Drone Was Replaced*: program a farming drone in HoodScript, one level at
136
+ a time. Same language, same crash reports — the game just adds a `bot`.
137
+
138
+ ```bash
139
+ pip install "hoodscript[arcade]"
140
+ hoodarcade # Big Mama's Cookout · BeatLab 808 · Drop Day
141
+ hoodarcade play cookout 1 # edit the solution file; the stage re-runs on save
142
+ ```
143
+
123
144
  ## Learn
124
145
 
125
146
  - [`docs/onboarding.md`](docs/onboarding.md) — from zero to a running program in ten minutes
@@ -50,14 +50,16 @@ To protect host environments against runaway workloads, the sandbox enforces thr
50
50
 
51
51
  ## 4. Code Execution Audit
52
52
 
53
- `exec`/`eval` appear in exactly four places, all on code objects produced by
53
+ `exec`/`eval` appear in exactly six places, all on code objects produced by
54
54
  `compile()` from the transpiler's output of the user's own source — never on
55
55
  text from anywhere else:
56
56
  1. `src/hoodscript/cli.py` — running a file
57
57
  2. `src/hoodscript/repl.py` — the interactive session (`eval` first, `exec` fallback)
58
58
  3. `src/hoodscript/debugger.py` — running a file under debugpy
59
59
  4. `src/hoodscript/tutor.py` — running a curriculum lesson
60
- `tests/security/test_exec_sites.py` fails if a fifth appears.
60
+ 5. `src/hoodscript/kernel/kernel.py` — executing notebook cells in the HoodScript kernel
61
+ 6. `src/hoodscript/kernel/magics.py` — executing `%%hood` cells in IPython / Google Colab
62
+ `tests/security/test_exec_sites.py` fails if a seventh appears.
61
63
 
62
64
  ### Why this is safe and equivalent to `compile()`:
63
65
  - `transpile()` performs strictly lexical substitution over Python's `tokenize.tokenize` stream and deterministic character-preserving pattern transforms (Rules R1–R12).
@@ -0,0 +1,45 @@
1
+ # ADR-0004: No Regional Dialect Overlays (Rule Zero Stands)
2
+
3
+ ## Status
4
+ Accepted (2026-09-12)
5
+
6
+ ## Context
7
+ A proposal asked for a "modular regional dialect engine": token overlays for
8
+ Bay Area, Atlanta, DMV, and UK Drill / MLE slang, selectable via `hood.toml` or
9
+ `--dialect`, resolving to standard HoodScript tokens before transpilation.
10
+
11
+ ## Decision
12
+ **Not adopted.** The keyword set is governed by Rule Zero and the sourcing
13
+ procedure in `hoodscript/docs/lexical-sourcing.md` §5. A dialect overlay is a
14
+ keyword table; every entry in it would need the same evidence as every other
15
+ keyword, and an owner-signed `GRAMMAR.md` revision. Four overlays of roughly
16
+ fifteen words each is four times the size of the entire v1.1 reconciliation.
17
+
18
+ Three further reasons:
19
+
20
+ 1. **It grows the wrong tier.** The language's thesis is Tier A — AAVE aspect
21
+ marking (`be`, `steady`, `BIN`, `done`) mapped onto execution semantics.
22
+ Overlays add only Tier B naming, which was deliberately capped small:
23
+ "every alias is a thing to learn, and 1:1 legibility suffers as aliases
24
+ grow." Regional slang is also the most perishable vocabulary there is,
25
+ which is exactly what Rule Zero excludes.
26
+ 2. **The mechanism is the known failure mode.** "Resolve dialect tokens to
27
+ standard tokens first" is the private-keyword-map pattern that three
28
+ external batches reintroduced in one day (2026-09-11/12), two of which
29
+ silently changed the meaning of `dip`. See CHANGELOG, QA sections.
30
+ 3. **A player who learns a dialect learns a language that runs nowhere else.**
31
+ The 1:1 promise is that what you write in HoodScript is HoodScript.
32
+
33
+ ## The door that stays open
34
+ The named varieties are real objects of sociolinguistic study. A *cited*
35
+ extension — one variety, each word through the seven steps, `UNVERIFIED`
36
+ where the literature is thin, signed by the owner — would be a legitimate
37
+ Tier B addition and can be proposed with `PROMPTS.md` §2.1. It is a sourcing
38
+ sprint first and a loader second, if ever.
39
+
40
+ ## Consequences
41
+ - No `--dialect` flag, no dialect section in any config, no overlay loader.
42
+ - `constants.py` remains the single keyword table; `patterns.py` the single
43
+ multi-token layer.
44
+ - Proposals that arrive with a dialect map are declined at review with a
45
+ pointer to this ADR.
@@ -0,0 +1,59 @@
1
+ (* HoodScript v1.1 — formal grammar (EBNF).
2
+ Descriptive: the implementation is a token rewrite (src/hoodscript/transpiler.py)
3
+ plus the pattern rules R1–R12 (src/hoodscript/patterns.py), not a parser.
4
+ This file is extracted verbatim from GRAMMAR.md; tests/test_grammar_ebnf.py
5
+ fails if the two drift. Edit GRAMMAR.md, then regenerate:
6
+ python scripts/gen_ebnf.py > docs/grammar.ebnf
7
+ *)
8
+
9
+ program = { statement } ;
10
+
11
+ statement = output_stmt | assignment | const_decl | func_def | class_def
12
+ | return_stmt | habitual_loop | continuative_loop | while_loop
13
+ | conditional | try_stmt | throw_stmt | import_stmt
14
+ | loop_control | pass_stmt | python_stmt | expr_stmt ;
15
+
16
+ output_stmt = "holla" [ expression { "," expression } | "(" [ args ] ")" ] ;
17
+ input_expr = "ask" ( expression | "(" [ args ] ")" ) ;
18
+ assignment = target "=" expression ;
19
+ const_decl = "BIN" IDENT "=" expression ;
20
+
21
+ func_def = [ "finna" ] "bet" IDENT "(" [ params ] ")" ":" block ;
22
+ return_stmt = ( "dip" | "return" ) [ expression ] ;
23
+ class_def = "fam" IDENT [ "(" IDENT { "," IDENT } ")" ] ":" block ;
24
+
25
+ habitual_loop = "be" target "in" expression ":" block ;
26
+ continuative_loop = "steady" ":" block ;
27
+ while_loop = "while" expression ":" block ;
28
+ loop_control = "skip" | "break" ;
29
+ pass_stmt = "chill" ;
30
+
31
+ conditional = "if" expression ":" block
32
+ { "else" "if" expression ":" block }
33
+ [ "else" ":" block ] ;
34
+
35
+ try_stmt = "tryna" ":" block { handler } [ "regardless" ":" block ] ;
36
+ handler = "catch" [ expression [ "as" IDENT ] ] ":" block ;
37
+ throw_stmt = "throw" [ expression ] ;
38
+
39
+ import_stmt = "import" dotted [ "as" IDENT ]
40
+ | "from" dotted "import" IDENT { "," IDENT } ;
41
+
42
+ python_stmt = (* any Python statement: with, match, del, global, nonlocal,
43
+ assert, yield, decorators, comprehensions — passed through *) ;
44
+
45
+ block = INDENT { statement } DEDENT ;
46
+
47
+ expression = or_expr ;
48
+ or_expr = and_expr { "or" and_expr } ;
49
+ and_expr = not_expr { "and" not_expr } ;
50
+ not_expr = [ "ain't" [ "nobody" ] | "not" ] comparison ;
51
+ comparison = term { comp_op term } ;
52
+ primary = NUMBER | STRING | IDENT
53
+ | "cap" | "no" "cap" | "None"
54
+ | "it's" expression
55
+ | "done" expression
56
+ | input_expr
57
+ | "(" expression ")"
58
+ | list_lit | dict_lit | range_lit | python_expr ;
59
+ range_lit = expression ".." expression ;
@@ -219,14 +219,42 @@ Speaks the Language Server Protocol over stdio. Provides:
219
219
  Point any LSP-capable editor at that command for the `hoodscript` language ID.
220
220
  A VS Code extension manifest lives in `editors/vscode/`.
221
221
 
222
- ## 11. Run the tests
222
+ ## 11. Jupyter Notebooks & Google Colab
223
+
224
+ Use HoodScript interactively inside JupyterLab, classic Notebooks, or Google Colab:
225
+
226
+ ### Option A: Dedicated Jupyter Kernel
227
+ ```bash
228
+ pip install hoodscript[jupyter]
229
+ hoodscript kernel install
230
+ jupyter lab
231
+ ```
232
+ Select the **HoodScript** kernel from the launcher. Every cell executes native HoodScript with tab completion and rich plain-English JPE error cards.
233
+
234
+ ### Option B: Google Colab & Existing Python Notebooks
235
+ In the first cell:
236
+ ```python
237
+ !pip install hoodscript[jupyter]
238
+ %load_ext hoodscript
239
+ ```
240
+ Now write HoodScript in any cell using `%%hood`:
241
+ ```ipython
242
+ %%hood
243
+ bet calculate(x):
244
+ dip x * 10
245
+
246
+ holla "Result:", calculate(4.2)
247
+ ```
248
+ Preview the generated Python anytime with `%%hood_transpile`.
249
+
250
+ ## 12. Run the tests
223
251
 
224
252
  ```bash
225
253
  pytest # with the venv
226
254
  PYTHONPATH=src pytest tests/ # without an editable install
227
255
  ```
228
256
 
229
- ## 12. Where to go next
257
+ ## 13. Where to go next
230
258
 
231
259
  - [`curriculum.md`](curriculum.md) — ten lessons covering the whole language
232
260
  - [`../agents.md`](../agents.md) — how the transpiler, importer, cache, and
@@ -0,0 +1,142 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# HoodScript Interactive Quickstart Notebook\n",
8
+ "\n",
9
+ "Welcome to **HoodScript** in Jupyter! HoodScript maps authentic AAVE keywords **1:1 to Python 3** and explains every error in **plain conversational English**.\n",
10
+ "\n",
11
+ "### Two Ways to Use HoodScript in Notebooks:\n",
12
+ "1. **Native HoodScript Kernel**: Select `HoodScript` from the kernel dropdown.\n",
13
+ "2. **IPython Magic**: In a standard Python notebook or Google Colab, run `%load_ext hoodscript` and use `%%hood` at the top of cells."
14
+ ]
15
+ },
16
+ {
17
+ "cell_type": "code",
18
+ "execution_count": null,
19
+ "metadata": {},
20
+ "outputs": [],
21
+ "source": [
22
+ "# Lesson 1: Values, Booleans, and holla\n",
23
+ "name = \"Khris\"\n",
24
+ "age = 28\n",
25
+ "verified = no cap # True\n",
26
+ "fake = cap # False\n",
27
+ "\n",
28
+ "holla \"User:\", name, \"Age:\", age, \"Verified:\", verified"
29
+ ]
30
+ },
31
+ {
32
+ "cell_type": "markdown",
33
+ "metadata": {},
34
+ "source": [
35
+ "### Live Transpilation Inspection\n",
36
+ "HoodScript adheres strictly to the **1:1 Law**: every line of HoodScript corresponds to valid Python with preserved line numbers.\n",
37
+ "Use `%hood_transpile` to inspect the generated Python code:"
38
+ ]
39
+ },
40
+ {
41
+ "cell_type": "code",
42
+ "execution_count": null,
43
+ "metadata": {},
44
+ "outputs": [],
45
+ "source": [
46
+ "%hood_transpile\n",
47
+ "be i in 1..5:\n",
48
+ " if i == 3:\n",
49
+ " skip\n",
50
+ " holla \"Lap:\", i"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "markdown",
55
+ "metadata": {},
56
+ "source": [
57
+ "### Loops and Inclusive Ranges: `be` and `1..n`\n",
58
+ "`be x in xs` represents habitual action (Python's `for x in xs`). `1..5` is an inclusive range (1, 2, 3, 4, 5)."
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
67
+ "total = 0\n",
68
+ "be i in 1..10:\n",
69
+ " total = total + i\n",
70
+ "\n",
71
+ "holla \"Sum of 1..10 is:\", total"
72
+ ]
73
+ },
74
+ {
75
+ "cell_type": "markdown",
76
+ "metadata": {},
77
+ "source": [
78
+ "### Functions and Classes: `bet`, `dip`, and `fam`\n",
79
+ "`bet` defines a function; `dip` returns with a value; `fam` defines a class."
80
+ ]
81
+ },
82
+ {
83
+ "cell_type": "code",
84
+ "execution_count": null,
85
+ "metadata": {},
86
+ "outputs": [],
87
+ "source": [
88
+ "bet apply_discount(price, pct=0.15):\n",
89
+ " dip price * (1.0 - pct)\n",
90
+ "\n",
91
+ "fam Shopper:\n",
92
+ " bet __init__(self, name, wallet):\n",
93
+ " self.name = name\n",
94
+ " self.wallet = wallet\n",
95
+ "\n",
96
+ " bet purchase(self, item_name, original_price):\n",
97
+ " final_price = apply_discount(original_price)\n",
98
+ " self.wallet = self.wallet - final_price\n",
99
+ " holla self.name, \"bought\", item_name, \"for\", final_price, \"| Balance remaining:\", self.wallet\n",
100
+ "\n",
101
+ "buyer = Shopper(\"Sam\", 150.0)\n",
102
+ "buyer.purchase(\"Sneakers\", 80.0)"
103
+ ]
104
+ },
105
+ {
106
+ "cell_type": "markdown",
107
+ "metadata": {},
108
+ "source": [
109
+ "### Plain-English Error Handling: `tryna`, `catch`, and `ZeroSplitTrip`\n",
110
+ "Exceptions are never dumped as raw Python tracebacks; they are rendered with plain-English explanations, causes, and suggestions."
111
+ ]
112
+ },
113
+ {
114
+ "cell_type": "code",
115
+ "execution_count": null,
116
+ "metadata": {},
117
+ "outputs": [],
118
+ "source": [
119
+ "tryna:\n",
120
+ " result = 100 / 0\n",
121
+ "catch ZeroSplitTrip as err:\n",
122
+ " holla \"Caught expected error:\", err\n",
123
+ "regardless:\n",
124
+ " holla \"Execution completed clean.\""
125
+ ]
126
+ }
127
+ ],
128
+ "metadata": {
129
+ "language_info": {
130
+ "name": "hoodscript",
131
+ "file_extension": ".hs",
132
+ "mimetype": "text/x-hoodscript"
133
+ },
134
+ "kernelspec": {
135
+ "name": "hoodscript",
136
+ "display_name": "HoodScript",
137
+ "language": "hoodscript"
138
+ }
139
+ },
140
+ "nbformat": 4,
141
+ "nbformat_minor": 2
142
+ }
@@ -0,0 +1,10 @@
1
+ # Stage 1: Four on the Floor
2
+ # Instructions: Load 16-step patterns for 'Kick' and 'Snare'.
3
+
4
+ kicks = [0, 4, 8, 12]
5
+ snares = [4, 12]
6
+
7
+ sequencer.load_track("Kick", kicks)
8
+ sequencer.load_track("Snare", snares)
9
+ sequencer.play()
10
+ holla("Classic 4-on-the-floor sequence loaded!")
@@ -0,0 +1,15 @@
1
+ # Stage 2: Trap Hat Triplets
2
+ # Instructions: Generate hi-hat steps combining straight 8ths and a triplet roll.
3
+
4
+ hats = []
5
+ # Standard 8th notes on even steps 0 to 10
6
+ be step in range(12):
7
+ if step % 2 == 0:
8
+ hats.append(step)
9
+
10
+ # Triplet roll on turnaround steps 12 to 15
11
+ be step in range(12, 16):
12
+ hats.append(step)
13
+
14
+ sequencer.load_track("HiHat", hats)
15
+ holla("Trap hats rolling across matrix: ", hats)
@@ -0,0 +1,11 @@
1
+ # Stage 3: Soul Sample Chopper
2
+ # Instructions: Chop 16 consecutive 1000ms slices onto pads 1 to 16, reversing every 4th pad.
3
+
4
+ be i in range(1, 17):
5
+ start_ms = (i - 1) * 1000
6
+ end_ms = i * 1000
7
+ mpc.chop_sample(start_ms, end_ms, i)
8
+ if i % 4 == 0:
9
+ mpc.reverse_pad(i)
10
+
11
+ holla("Vinyl chopped and reversed into 16 quantized MPC pads!")
@@ -0,0 +1,14 @@
1
+ # Stage 4: 808 Slide Calculus
2
+ # Instructions: Define calculate_808_glide(start_note, end_note, steps) returning linear frequency curve.
3
+
4
+ bet calculate_808_glide(start_note, end_note, steps):
5
+ freqs = {"C1": 32.70, "D1": 36.71, "E1": 41.20, "F1": 43.65, "G1": 49.00, "A1": 55.00}
6
+ f_start = freqs[start_note]
7
+ f_end = freqs[end_note]
8
+
9
+ result = []
10
+ step_delta = (f_end - f_start) / (steps - 1)
11
+ be i in range(steps):
12
+ result.append(round(f_start + (i * step_delta), 2))
13
+
14
+ dip result
@@ -0,0 +1,13 @@
1
+ # Stage 5: The Metro Drop
2
+ # Instructions: Assemble full track arrangement, drop producer tag, and render final WAV.
3
+
4
+ bet produce_metro_drop(mpc, sequencer, mastering):
5
+ mpc.set_bpm(144)
6
+
7
+ sequencer.load_track("Kick", [0, 6, 8, 14])
8
+ sequencer.load_track("Snare", [4, 12])
9
+ sequencer.load_track("808", [0, 6, 8, 14])
10
+ sequencer.load_track("HiHat", [0, 2, 4, 6, 8, 10, 12, 13, 14, 15])
11
+
12
+ mastering.drop_tag("metro_tag.wav", 4)
13
+ mastering.render_wav("hit_single_master.wav")
@@ -0,0 +1,9 @@
1
+ # Stage 1: Grill Master Basics
2
+ # Instructions: Loop through all grill items, season with Lawry's, and flip twice so they are cooked!
3
+
4
+ items = grill.get_items()
5
+ be item in items:
6
+ grill.season(item, "Lawry's Seasoned Salt")
7
+ grill.flip(item)
8
+ grill.flip(item)
9
+ holla("Cooked to perfection: ", item)