feat(data-track/week-6): add Week 6 practice exercises#25
Conversation
Week 6 (Azure fundamentals) is paper-based in the chapter because the real
work happens on shared Azure infra. These exercises are the Codespace-runnable
counterpart that trains the Python + diagnosis muscles before learners spend
Azure credits.
Layout:
exercise_1/ Trace a resource group (mock `az resource list` JSON + classifier)
exercise_2/ End-to-end blob verification (azure-storage-blob; graceful skip
without AZURE_STORAGE_CONNECTION_STRING)
exercise_3/ Debug a broken Postgres connection string (urllib.parse)
exercise_4/ Dry-run an `az containerapp job create` command + self-check
exercise_5/ Cost estimation arithmetic across four scenarios
Verified end-to-end against the `# Expected output:` block in each file:
Ex1 solution prints the 7-row table, 5/7 idle billers - PASS
Ex2 starter exits 1 with the documented "set this env var" message - PASS
Ex3 solution returns 3 problems and the fixed URL - PASS
Ex4 solution prints the 10-flag command and self-check OK - PASS
Ex5 solution prints scenarios A-D with the expected EUR totals - PASS
Ex1 ships a mock `az_resource_list_output.json` so Codespace learners can run
the exercise without Azure access; students with their own resource group can
overwrite the file with real `az resource list --output json` output.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lassebenni
left a comment
There was a problem hiding this comment.
Local review by Claude — 0 issues found (0 blocking, 0 warnings)
Note: this PR was authored by lassebenni (the same account running the review), so this is a COMMENT review with validator results, not an APPROVE.
Validators run
Adapted the dispatcher to Python practice exercises (this is HackYourFuture/Learning-Resources, not a dbt repo):
| Check | Result |
|---|---|
python3 -m py_compile on all 10 .py files |
✅ 10/10 syntax clean |
| Starter exits non-zero on direct run (5 starters) | ✅ 5/5 fail correctly (ex1/3/4/5 raise NotImplementedError; ex2 prints env-var instructions and exits 1) |
| Solution runs cleanly (4 non-cloud solutions: ex1/3/4/5) | ✅ 4/4 exit 0 with sensible output |
| ex2 solution (Azure-dependent) | ✅ AST parses; runtime requires AZURE_STORAGE_CONNECTION_STRING (correct) |
json.load() on exercise_1/az_resource_list_output.json |
✅ Parses |
Conflict markers (<<<<<<<) |
✅ None |
Spot-check evidence
ex1solution output ends with:5 of 7 resources bill while idle.(matches chapter's resource-billing breakdown)ex3solution prints 3 diagnoses + fixed URL (matches the chapter's connection-string anatomy lesson)ex4solution printsSelf-check OK. All required flags are present.(verifies the command-builder pattern)ex5solution prints all 4 scenarios with correct EUR arithmetic (matches Ch6 cost-awareness scenarios)
Heads-up: 7 unresolved Copilot threads exist on this PR independently
copilot-pull-request-reviewer has already left 7 inline review threads on the current HEAD (87e8905). My local validators are independent of those and pass cleanly; the Copilot threads are stylistic/accuracy nits on docstrings, comments, and one substantive note about .env.example using source without export. They are not regressions in this PR (every file is net-new).
Verdict
PR is functionally clean: all validators pass, every exercise's starter fails by default, every runnable solution executes cleanly, the Azure-dependent solution AST-parses. Ready to merge from a code-correctness standpoint. The 7 Copilot threads can be addressed in a follow-up commit if any are worth applying (next pass via /evaluate-pr-comments would be the right tool for that, separate from this validator run).
Six minor doc inaccuracies + one real bug in .env.example. Per-file:
- exercise_1/exercise.py + solutions/exercise.py:
Comment told students "az resource list ... > my_resources.json" but
the script reads "az_resource_list_output.json" via SAMPLE_PATH.
Aligned the suggested filename so a student who swaps in their own
Azure output writes to the file the script actually reads.
- exercise_2/exercise.py:
Hardcoded "(42 bytes)" in the expected-output comment depended on
JSON serialisation choices (indent vs no-indent). Replaced with
"(N bytes)" so students don't read it as a strict equality check.
- exercise_3/solutions/exercise.py:
fix() rebuilt userinfo from parsed.username/parsed.password, which
loses percent-encoding (urllib decodes %xx) and would re-break URLs
whose passwords contain '@' or ':'. Switched to slicing the original
parsed.netloc up to '@' so the encoded form round-trips. Also fixed
query-param handling: urlencode({k: v[0] ...}) collapsed multi-valued
query params; replaced with urlencode(query, doseq=True) to preserve
duplicates. Solution output unchanged on the chapter's broken-URL
fixture (verified by re-running).
- exercise_4/exercise.py + solutions/exercise.py:
Docstring referenced "--container name" (wrong: actual flag is
--container-name) and said the self-check "imports your
build_create_command() result" (wrong: it calls the function).
Fixed both — small but worth aligning because the chapter is about
Azure CLI flag accuracy.
- exercise_2/.env.example (the real bug):
Previous form would fail for any student who followed the documented
`source .env` path:
1. Plain `VAR=value` in a sourced file sets a SHELL variable, not
an environment variable — python3 subprocesses don't see it, so
the script reports "AZURE_STORAGE_CONNECTION_STRING is not set"
even after the student "set" it.
2. The value contains unquoted semicolons; bash parses them as
command separators, so `source` triggers "command not found"
errors for "AccountName=...", "AccountKey=...", etc., and the
variable ends up only partially set.
Now: value is double-quoted, and the instructions name two working
paths (`set -a && source .env && set +a` for shell, python-dotenv
for Python). Explicit warning about plain `source .env` failing.
All six .py files compile clean. Ex3 solution still produces the
identical output on the chapter's broken-URL fixture after the
urllib refactor.
Keep the rewritten week-6 exercises (bash ex1/4/5, live Postgres ex3, Key Vault ex2, portal cost ex5) and drop the superseded scaffold files from main.
…age host (#26) * feat(data-track/week-6): scaffold 5 exercises with in-place solutions Week 6 (Azure fundamentals) is paper-based in the chapter because the real work happens on shared Azure infra. These exercises are the Codespace-runnable counterpart that trains the Python + diagnosis muscles before learners spend Azure credits. Layout: exercise_1/ Trace a resource group (mock `az resource list` JSON + classifier) exercise_2/ End-to-end blob verification (azure-storage-blob; graceful skip without AZURE_STORAGE_CONNECTION_STRING) exercise_3/ Debug a broken Postgres connection string (urllib.parse) exercise_4/ Dry-run an `az containerapp job create` command + self-check exercise_5/ Cost estimation arithmetic across four scenarios Verified end-to-end against the `# Expected output:` block in each file: Ex1 solution prints the 7-row table, 5/7 idle billers - PASS Ex2 starter exits 1 with the documented "set this env var" message - PASS Ex3 solution returns 3 problems and the fixed URL - PASS Ex4 solution prints the 10-flag command and self-check OK - PASS Ex5 solution prints scenarios A-D with the expected EUR totals - PASS Ex1 ships a mock `az_resource_list_output.json` so Codespace learners can run the exercise without Azure access; students with their own resource group can overwrite the file with real `az resource list --output json` output. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(week-6 exercises): address PR #25 Copilot review Six minor doc inaccuracies + one real bug in .env.example. Per-file: - exercise_1/exercise.py + solutions/exercise.py: Comment told students "az resource list ... > my_resources.json" but the script reads "az_resource_list_output.json" via SAMPLE_PATH. Aligned the suggested filename so a student who swaps in their own Azure output writes to the file the script actually reads. - exercise_2/exercise.py: Hardcoded "(42 bytes)" in the expected-output comment depended on JSON serialisation choices (indent vs no-indent). Replaced with "(N bytes)" so students don't read it as a strict equality check. - exercise_3/solutions/exercise.py: fix() rebuilt userinfo from parsed.username/parsed.password, which loses percent-encoding (urllib decodes %xx) and would re-break URLs whose passwords contain '@' or ':'. Switched to slicing the original parsed.netloc up to '@' so the encoded form round-trips. Also fixed query-param handling: urlencode({k: v[0] ...}) collapsed multi-valued query params; replaced with urlencode(query, doseq=True) to preserve duplicates. Solution output unchanged on the chapter's broken-URL fixture (verified by re-running). - exercise_4/exercise.py + solutions/exercise.py: Docstring referenced "--container name" (wrong: actual flag is --container-name) and said the self-check "imports your build_create_command() result" (wrong: it calls the function). Fixed both — small but worth aligning because the chapter is about Azure CLI flag accuracy. - exercise_2/.env.example (the real bug): Previous form would fail for any student who followed the documented `source .env` path: 1. Plain `VAR=value` in a sourced file sets a SHELL variable, not an environment variable — python3 subprocesses don't see it, so the script reports "AZURE_STORAGE_CONNECTION_STRING is not set" even after the student "set" it. 2. The value contains unquoted semicolons; bash parses them as command separators, so `source` triggers "command not found" errors for "AccountName=...", "AccountKey=...", etc., and the variable ends up only partially set. Now: value is double-quoted, and the instructions name two working paths (`set -a && source .env && set +a` for shell, python-dotenv for Python). Explicit warning about plain `source .env` failing. All six .py files compile clean. Ex3 solution still produces the identical output on the chapter's broken-URL fixture after the urllib refactor. * feat(week-6): align practice exercises with Key Vault and actual storage host * chore: remove idle billing check from week-6 exercise 1 * chore: remove billing references from exercise 1 python docstrings * chore: convert exercises 1 and 4 to bash scripts * chore: convert exercise 3 to connect to database, insert and query * chore: ingest data from local csv in exercise 3 psycopg2 operations * chore: convert exercise 5 to query live Cost Management API * chore: add schema search_path setup to exercise 3 to prevent clashing * chore: pre-configure endpoint and payload templates in exercise 5 starter * chore: convert cost management exercise 5 to use official azure cost SDK * chore: add pyproject.toml configuration files for uv package management * chore: remove redundant requirements.txt files and update READMEs to use uv sync * feat(week-6): update exercises 4 & 5 with SDK, docs and commands * fix(week-6): align exercises with shared infra and portal cost workflow Sync README and exercise docs with live Azure resources: ex1 adds resource classification table, ex3 documents Key Vault + schema setup, ex4 targets rg-hyf-data/hyfregistry with validate_flags.sh, and ex5 replaces the Cost Management SDK with a portal Cost Analysis worksheet. * fix(week-6/ex3): scaffold CREATE TABLE DDL to reduce starter TODO count --------- Co-authored-by: Lasse Benninga <devops.pipeline@example.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds
data-track/week-6/with five Codespace-runnable practice exercises that support the Week 6 (Azure fundamentals) practice chapter. The chapter is paper-based by design because the assignment runs against shared Azure infrastructure; these exercises give learners the Python + diagnosis muscle they need before they spend Azure credits.az resource listJSON)Exercise 1 ships a representative mock
az_resource_list_output.jsonso Codespace learners can complete it offline; students with Azure access can drop in realaz resource list --output jsonoutput to label their actual environment.Exercise 2 detects a missing
AZURE_STORAGE_CONNECTION_STRINGand exits with a clear "ask your teacher" message, so the starter still gives the learner a useful signal in a Codespace without infrastructure.Verification
Every solution ran from a fresh shell and matched the
# Expected output:block in its file:az containerapp job createcommand, self-check OK - PASSLinked curriculum
Practice chapter that consumes these exercises (in the curriculum repo):
Data Track/Week 6/week_6__7_practice.md. The chapter wire-up (Codespace link + per-exercise 📦 Files callouts) lands in a separate datatrack PR after this merges.Test plan
data-track/week-6/exercise_3/; runpython3 exercise.pyand confirmNotImplementedError, thenpython3 solutions/exercise.pyand confirm the expected output.exercise_1,exercise_4,exercise_5.exercise_2, without setting the env var, runpython3 exercise.pyand confirm the graceful "set this env var" failure (exit 1).pip install -r exercise_2/requirements.txtsucceeds (azure-storage-blob==12.19.0).🤖 Generated with Claude Code