Skip to content

feat(data-track/week-6): add Week 6 practice exercises#25

Merged
lassebenni merged 1 commit into
mainfrom
feat/data-track-week-6
Jun 3, 2026
Merged

feat(data-track/week-6): add Week 6 practice exercises#25
lassebenni merged 1 commit into
mainfrom
feat/data-track-week-6

Conversation

@lassebenni

Copy link
Copy Markdown
Collaborator

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.

# Exercise Type Azure access?
1 Trace a Resource Group CLI inventory + idle-billing labelling No (mock az resource list JSON)
2 End-to-End Blob Verification Python upload + CLI verify Yes (graceful skip without env var)
3 Debug a Broken Connection String URL parsing No (pure Python)
4 Dry-Run a Container App Job Command writing + self-check No (pure Python)
5 Cost Estimation Challenge Pricing arithmetic No (pure Python)

Exercise 1 ships a representative mock az_resource_list_output.json so Codespace learners can complete it offline; students with Azure access can drop in real az resource list --output json output to label their actual environment.

Exercise 2 detects a missing AZURE_STORAGE_CONNECTION_STRING and 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:

  • Ex1: 7-row table, 5/7 resources flagged "bills idle" - PASS
  • Ex2 (starter): exits 1 with documented instructions when env var unset - PASS (full solution flow documented; needs the shared storage account to execute end-to-end)
  • Ex3: lists 3 problems (host, port, sslmode) and returns the fixed Azure FQDN URL - PASS
  • Ex4: prints the 10-flag az containerapp job create command, self-check OK - PASS
  • Ex5: scenarios A-D produce EUR 19.74, 8.96, 0.19, and a 12.24 saving - PASS

Linked 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

  • Open the repo in Codespaces; navigate into data-track/week-6/exercise_3/; run python3 exercise.py and confirm NotImplementedError, then python3 solutions/exercise.py and confirm the expected output.
  • Repeat for exercise_1, exercise_4, exercise_5.
  • In exercise_2, without setting the env var, run python3 exercise.py and confirm the graceful "set this env var" failure (exit 1).
  • pip install -r exercise_2/requirements.txt succeeds (azure-storage-blob==12.19.0).

🤖 Generated with Claude Code

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>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 7 comments.

Comment thread data-track/week-6/exercise_1/exercise.py
Comment thread data-track/week-6/exercise_1/solutions/exercise.py
Comment thread data-track/week-6/exercise_2/exercise.py
Comment thread data-track/week-6/exercise_3/solutions/exercise.py
Comment thread data-track/week-6/exercise_4/exercise.py
Comment thread data-track/week-6/exercise_4/solutions/exercise.py
Comment thread data-track/week-6/exercise_2/.env.example

@lassebenni lassebenni left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • ex1 solution output ends with: 5 of 7 resources bill while idle. (matches chapter's resource-billing breakdown)
  • ex3 solution prints 3 diagnoses + fixed URL (matches the chapter's connection-string anatomy lesson)
  • ex4 solution prints Self-check OK. All required flags are present. (verifies the command-builder pattern)
  • ex5 solution 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).

@lassebenni lassebenni merged commit 9cd3ad4 into main Jun 3, 2026
1 of 2 checks passed
lassebenni pushed a commit that referenced this pull request Jun 7, 2026
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.
lassebenni pushed a commit that referenced this pull request Jun 7, 2026
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.
lassebenni added a commit that referenced this pull request Jun 7, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants